clang: adjust formatting rules (#1015)

This commit is contained in:
ReenigneArcher 2023-03-27 21:45:29 -04:00 committed by GitHub
commit 21eb4eb6dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
103 changed files with 26883 additions and 25173 deletions

View file

@ -7,7 +7,7 @@
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveAssignments: false
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
@ -18,8 +18,9 @@ AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
AlignTrailingComments: false
AlwaysBreakAfterReturnType: All
AlwaysBreakTemplateDeclarations: MultiLine
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
@ -37,32 +38,32 @@ BraceWrapping:
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 2
IndentCaseLabels: false
IndentPPDirectives: None
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 2
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false

View file

@ -0,0 +1,40 @@
# standard imports
import os
import subprocess
# variables
directories = [
'src',
'tools',
os.path.join('third-party', 'glad'),
os.path.join('third-party', 'nvfbc'),
os.path.join('third-party', 'wayland-protocols')
]
file_types = [
'cpp',
'h',
'm',
'mm'
]
def clang_format(file: str):
print(f'Formatting {file} ...')
subprocess.run(['clang-format', '-i', file])
def main():
"""
Main entry point.
"""
# walk the directories
for directory in directories:
for root, dirs, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
if os.path.isfile(file_path) and file.rsplit('.')[-1] in file_types:
clang_format(file=file_path)
if __name__ == '__main__':
main()

View file

@ -25,10 +25,13 @@ struct audio_ctx_t {
platf::sink_t sink;
};
static int start_audio_control(audio_ctx_t &ctx);
static void stop_audio_control(audio_ctx_t &);
static int
start_audio_control(audio_ctx_t &ctx);
static void
stop_audio_control(audio_ctx_t &);
int map_stream(int channels, bool quality);
int
map_stream(int channels, bool quality);
constexpr auto SAMPLE_RATE = 48000;
@ -85,7 +88,8 @@ opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
auto control_shared = safe::make_shared<audio_ctx_t>(start_audio_control, stop_audio_control);
void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
void
encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
auto packets = mail::man->queue<packet_t>(mail::audio_packets);
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
@ -121,7 +125,8 @@ void encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
}
}
void capture(safe::mail_t mail, config_t config, void *channel_data) {
void
capture(safe::mail_t mail, config_t config, void *channel_data) {
auto shutdown_event = mail->event<bool>(mail::shutdown);
auto stream = &stream_configs[map_stream(config.channels, config.flags[config_t::HIGH_QUALITY])];
@ -226,7 +231,8 @@ void capture(safe::mail_t mail, config_t config, void *channel_data) {
}
}
int map_stream(int channels, bool quality) {
int
map_stream(int channels, bool quality) {
int shift = quality ? 1 : 0;
switch (channels) {
case 2:
@ -239,7 +245,8 @@ int map_stream(int channels, bool quality) {
return STEREO;
}
int start_audio_control(audio_ctx_t &ctx) {
int
start_audio_control(audio_ctx_t &ctx) {
auto fg = util::fail_guard([]() {
BOOST_LOG(warning) << "There will be no audio"sv;
});
@ -266,7 +273,8 @@ int start_audio_control(audio_ctx_t &ctx) {
return 0;
}
void stop_audio_control(audio_ctx_t &ctx) {
void
stop_audio_control(audio_ctx_t &ctx) {
// restore audio-sink if applicable
if (!ctx.restore_sink) {
return;

View file

@ -41,7 +41,8 @@ struct config_t {
using buffer_t = util::buffer_t<std::uint8_t>;
using packet_t = std::pair<void *, buffer_t>;
void capture(safe::mail_t mail, config_t config, void *channel_data);
void
capture(safe::mail_t mail, config_t config, void *channel_data);
} // namespace audio
#endif

View file

@ -12,7 +12,8 @@ extern "C" {
using namespace std::literals;
namespace cbs {
void close(CodedBitstreamContext *c) {
void
close(CodedBitstreamContext *c) {
ff_cbs_close(&c);
}
@ -31,7 +32,8 @@ public:
std::fill_n((std::uint8_t *) this, sizeof(*this), 0);
}
frag_t &operator=(frag_t &&o) {
frag_t &
operator=(frag_t &&o) {
std::copy((std::uint8_t *) &o, (std::uint8_t *) (&o + 1), (std::uint8_t *) this);
o.data = nullptr;
@ -40,7 +42,6 @@ public:
return *this;
};
~frag_t() {
if (data || units) {
ff_cbs_fragment_free(this);
@ -48,7 +49,8 @@ public:
}
};
util::buffer_t<std::uint8_t> write(const cbs::ctx_t &cbs_ctx, std::uint8_t nal, void *uh, AVCodecID codec_id) {
util::buffer_t<std::uint8_t>
write(const cbs::ctx_t &cbs_ctx, std::uint8_t nal, void *uh, AVCodecID codec_id) {
cbs::frag_t frag;
auto err = ff_cbs_insert_unit_content(&frag, -1, nal, uh, nullptr);
if (err < 0) {
@ -73,14 +75,16 @@ util::buffer_t<std::uint8_t> write(const cbs::ctx_t &cbs_ctx, std::uint8_t nal,
return data;
}
util::buffer_t<std::uint8_t> write(std::uint8_t nal, void *uh, AVCodecID codec_id) {
util::buffer_t<std::uint8_t>
write(std::uint8_t nal, void *uh, AVCodecID codec_id) {
cbs::ctx_t cbs_ctx;
ff_cbs_init(&cbs_ctx, codec_id, nullptr);
return write(cbs_ctx, nal, uh, codec_id);
}
util::buffer_t<std::uint8_t> make_sps_h264(const AVCodecContext *ctx) {
util::buffer_t<std::uint8_t>
make_sps_h264(const AVCodecContext *ctx) {
H264RawSPS sps {};
/* b_per_p == ctx->max_b_frames for h264 */
@ -91,7 +95,6 @@ util::buffer_t<std::uint8_t> make_sps_h264(const AVCodecContext *ctx) {
auto mb_width = (FFALIGN(ctx->width, 16) / 16) * 16;
auto mb_height = (FFALIGN(ctx->height, 16) / 16) * 16;
sps.nal_unit_header.nal_ref_idc = 3;
sps.nal_unit_header.nal_unit_type = H264_NAL_SPS;
@ -168,7 +171,8 @@ util::buffer_t<std::uint8_t> make_sps_h264(const AVCodecContext *ctx) {
return write(sps.nal_unit_header.nal_unit_type, (void *) &sps.nal_unit_header, AV_CODEC_ID_H264);
}
hevc_t make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
hevc_t
make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
cbs::ctx_t ctx;
if (ff_cbs_init(&ctx, AV_CODEC_ID_H265, nullptr)) {
return {};
@ -184,7 +188,6 @@ hevc_t make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
return {};
}
auto vps_p = ((CodedBitstreamH265Context *) ctx->priv_data)->active_vps;
auto sps_p = ((CodedBitstreamH265Context *) ctx->priv_data)->active_sps;
@ -209,7 +212,6 @@ hevc_t make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
vui.transfer_characteristics = avctx->color_trc;
vui.matrix_coefficients = avctx->colorspace;
vui.vui_timing_info_present_flag = vps.vps_timing_info_present_flag;
vui.vui_num_units_in_tick = vps.vps_num_units_in_tick;
vui.vui_time_scale = vps.vps_time_scale;
@ -228,7 +230,6 @@ hevc_t make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
cbs::ctx_t write_ctx;
ff_cbs_init(&write_ctx, AV_CODEC_ID_H265, nullptr);
return hevc_t {
nal_t {
write(write_ctx, vps.nal_unit_header.nal_unit_type, (void *) &vps.nal_unit_header, AV_CODEC_ID_H265),
@ -242,7 +243,8 @@ hevc_t make_sps_hevc(const AVCodecContext *avctx, const AVPacket *packet) {
};
}
util::buffer_t<std::uint8_t> read_sps_h264(const AVPacket *packet) {
util::buffer_t<std::uint8_t>
read_sps_h264(const AVPacket *packet) {
cbs::ctx_t ctx;
if (ff_cbs_init(&ctx, AV_CODEC_ID_H264, nullptr)) {
return {};
@ -262,14 +264,16 @@ util::buffer_t<std::uint8_t> read_sps_h264(const AVPacket *packet) {
return write(h264->nal_unit_type, (void *) h264, AV_CODEC_ID_H264);
}
h264_t make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet) {
h264_t
make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet) {
return h264_t {
make_sps_h264(ctx),
read_sps_h264(packet),
};
}
bool validate_sps(const AVPacket *packet, int codec_id) {
bool
validate_sps(const AVPacket *packet, int codec_id) {
cbs::ctx_t ctx;
if (ff_cbs_init(&ctx, (AVCodecID) codec_id, nullptr)) {
return false;

View file

@ -22,13 +22,16 @@ struct h264_t {
nal_t sps;
};
hevc_t make_sps_hevc(const AVCodecContext *ctx, const AVPacket *packet);
h264_t make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet);
hevc_t
make_sps_hevc(const AVCodecContext *ctx, const AVPacket *packet);
h264_t
make_sps_h264(const AVCodecContext *ctx, const AVPacket *packet);
/**
* Check if SPS->VUI is present
*/
bool validate_sps(const AVPacket *packet, int codec_id);
bool
validate_sps(const AVPacket *packet, int codec_id);
} // namespace cbs
#endif

View file

@ -71,7 +71,8 @@ enum coder_e : int {
cavlc = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC,
};
std::optional<preset_e> preset_from_view(const std::string_view &preset) {
std::optional<preset_e>
preset_from_view(const std::string_view &preset) {
#define _CONVERT_(x) \
if (preset == #x##sv) return x
_CONVERT_(p1);
@ -85,7 +86,8 @@ std::optional<preset_e> preset_from_view(const std::string_view &preset) {
return std::nullopt;
}
std::optional<tune_e> tune_from_view(const std::string_view &tune) {
std::optional<tune_e>
tune_from_view(const std::string_view &tune) {
#define _CONVERT_(x) \
if (tune == #x##sv) return x
_CONVERT_(hq);
@ -96,7 +98,8 @@ std::optional<tune_e> tune_from_view(const std::string_view &tune) {
return std::nullopt;
}
std::optional<rc_e> rc_from_view(const std::string_view &rc) {
std::optional<rc_e>
rc_from_view(const std::string_view &rc) {
#define _CONVERT_(x) \
if (rc == #x##sv) return x
_CONVERT_(constqp);
@ -106,7 +109,8 @@ std::optional<rc_e> rc_from_view(const std::string_view &rc) {
return std::nullopt;
}
int coder_from_view(const std::string_view &coder) {
int
coder_from_view(const std::string_view &coder) {
if (coder == "auto"sv) return _auto;
if (coder == "cabac"sv || coder == "ac"sv) return cabac;
if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc;
@ -194,7 +198,8 @@ enum coder_e : int {
cavlc = AMF_VIDEO_ENCODER_CALV
};
std::optional<int> quality_from_view(const std::string_view &quality_type, int codec) {
std::optional<int>
quality_from_view(const std::string_view &quality_type, int codec) {
#define _CONVERT_(x) \
if (quality_type == #x##sv) return codec == 0 ? (int) quality_hevc_e::x : (int) quality_h264_e::x
_CONVERT_(quality);
@ -204,7 +209,8 @@ std::optional<int> quality_from_view(const std::string_view &quality_type, int c
return std::nullopt;
}
std::optional<int> rc_from_view(const std::string_view &rc, int codec) {
std::optional<int>
rc_from_view(const std::string_view &rc, int codec) {
#define _CONVERT_(x) \
if (rc == #x##sv) return codec == 0 ? (int) rc_hevc_e::x : (int) rc_h264_e::x
_CONVERT_(cqp);
@ -215,7 +221,8 @@ std::optional<int> rc_from_view(const std::string_view &rc, int codec) {
return std::nullopt;
}
std::optional<int> usage_from_view(const std::string_view &rc, int codec) {
std::optional<int>
usage_from_view(const std::string_view &rc, int codec) {
#define _CONVERT_(x) \
if (rc == #x##sv) return codec == 0 ? (int) usage_hevc_e::x : (int) usage_h264_e::x
_CONVERT_(transcoding);
@ -226,7 +233,8 @@ std::optional<int> usage_from_view(const std::string_view &rc, int codec) {
return std::nullopt;
}
int coder_from_view(const std::string_view &coder) {
int
coder_from_view(const std::string_view &coder) {
if (coder == "auto"sv) return _auto;
if (coder == "cabac"sv || coder == "ac"sv) return cabac;
if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc;
@ -252,7 +260,8 @@ enum cavlc_e : int {
disabled = false
};
std::optional<int> preset_from_view(const std::string_view &preset) {
std::optional<int>
preset_from_view(const std::string_view &preset) {
#define _CONVERT_(x) \
if (preset == #x##sv) return x
_CONVERT_(veryslow);
@ -266,7 +275,8 @@ std::optional<int> preset_from_view(const std::string_view &preset) {
return std::nullopt;
}
std::optional<int> coder_from_view(const std::string_view &coder) {
std::optional<int>
coder_from_view(const std::string_view &coder) {
if (coder == "auto"sv) return _auto;
if (coder == "cabac"sv || coder == "ac"sv) return disabled;
if (coder == "cavlc"sv || coder == "vlc"sv) return enabled;
@ -283,7 +293,8 @@ enum coder_e : int {
cavlc
};
int coder_from_view(const std::string_view &coder) {
int
coder_from_view(const std::string_view &coder) {
if (coder == "auto"sv) return _auto;
if (coder == "cabac"sv || coder == "ac"sv) return cabac;
if (coder == "cavlc"sv || coder == "vlc"sv) return cavlc;
@ -291,19 +302,22 @@ int coder_from_view(const std::string_view &coder) {
return -1;
}
int allow_software_from_view(const std::string_view &software) {
int
allow_software_from_view(const std::string_view &software) {
if (software == "allowed"sv || software == "forced") return 1;
return 0;
}
int force_software_from_view(const std::string_view &software) {
int
force_software_from_view(const std::string_view &software) {
if (software == "forced") return 1;
return 0;
}
int rt_from_view(const std::string_view &rt) {
int
rt_from_view(const std::string_view &rt) {
if (rt == "disabled" || rt == "off" || rt == "0") return 0;
return 1;
@ -431,19 +445,23 @@ sunshine_t sunshine {
{}, // prep commands
};
bool endline(char ch) {
bool
endline(char ch) {
return ch == '\r' || ch == '\n';
}
bool space_tab(char ch) {
bool
space_tab(char ch) {
return ch == ' ' || ch == '\t';
}
bool whitespace(char ch) {
bool
whitespace(char ch) {
return space_tab(ch) || endline(ch);
}
std::string to_string(const char *begin, const char *end) {
std::string
to_string(const char *begin, const char *end) {
std::string result;
KITTY_WHILE_LOOP(auto pos = begin, pos != end, {
@ -459,7 +477,8 @@ std::string to_string(const char *begin, const char *end) {
}
template <class It>
It skip_list(It skipper, It end) {
It
skip_list(It skipper, It end) {
int stack = 1;
while (skipper != end && stack) {
if (*skipper == '[') {
@ -511,7 +530,8 @@ parse_option(std::string_view::const_iterator begin, std::string_view::const_ite
std::make_pair(to_string(begin, end_name), to_string(begin_val, endl)));
}
std::unordered_map<std::string, std::string> parse_config(const std::string_view &file_content) {
std::unordered_map<std::string, std::string>
parse_config(const std::string_view &file_content) {
std::unordered_map<std::string, std::string> vars;
auto pos = std::begin(file_content);
@ -536,7 +556,8 @@ std::unordered_map<std::string, std::string> parse_config(const std::string_view
return vars;
}
void string_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input) {
void
string_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input) {
auto it = vars.find(name);
if (it == std::end(vars)) {
return;
@ -547,7 +568,8 @@ void string_f(std::unordered_map<std::string, std::string> &vars, const std::str
vars.erase(it);
}
void string_restricted_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input, const std::vector<std::string_view> &allowed_vals) {
void
string_restricted_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input, const std::vector<std::string_view> &allowed_vals) {
std::string temp;
string_f(vars, name, temp);
@ -559,7 +581,8 @@ void string_restricted_f(std::unordered_map<std::string, std::string> &vars, con
}
}
void path_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, fs::path &input) {
void
path_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, fs::path &input) {
// appdata needs to be retrieved once only
static auto appdata = platf::appdata();
@ -583,7 +606,8 @@ void path_f(std::unordered_map<std::string, std::string> &vars, const std::strin
}
}
void path_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input) {
void
path_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input) {
fs::path temp = input;
path_f(vars, name, temp);
@ -591,7 +615,8 @@ void path_f(std::unordered_map<std::string, std::string> &vars, const std::strin
input = temp.string();
}
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input) {
void
int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input) {
auto it = vars.find(name);
if (it == std::end(vars)) {
@ -616,7 +641,8 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
vars.erase(it);
}
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::optional<int> &input) {
void
int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::optional<int> &input) {
auto it = vars.find(name);
if (it == std::end(vars)) {
@ -642,7 +668,8 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
}
template <class F>
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input, F &&f) {
void
int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input, F &&f) {
std::string tmp;
string_f(vars, name, tmp);
if (!tmp.empty()) {
@ -651,7 +678,8 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
}
template <class F>
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::optional<int> &input, F &&f) {
void
int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::optional<int> &input, F &&f) {
std::string tmp;
string_f(vars, name, tmp);
if (!tmp.empty()) {
@ -659,7 +687,8 @@ void int_f(std::unordered_map<std::string, std::string> &vars, const std::string
}
}
void int_between_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input, const std::pair<int, int> &range) {
void
int_between_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input, const std::pair<int, int> &range) {
int temp = input;
int_f(vars, name, temp);
@ -670,7 +699,8 @@ void int_between_f(std::unordered_map<std::string, std::string> &vars, const std
}
}
bool to_bool(std::string &boolean) {
bool
to_bool(std::string &boolean) {
std::for_each(std::begin(boolean), std::end(boolean), [](char ch) { return (char) std::tolower(ch); });
return boolean == "true"sv ||
@ -681,7 +711,8 @@ bool to_bool(std::string &boolean) {
(std::find(std::begin(boolean), std::end(boolean), '1') != std::end(boolean));
}
void bool_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, bool &input) {
void
bool_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, bool &input) {
std::string tmp;
string_f(vars, name, tmp);
@ -692,7 +723,8 @@ void bool_f(std::unordered_map<std::string, std::string> &vars, const std::strin
input = to_bool(tmp);
}
void double_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, double &input) {
void
double_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, double &input) {
std::string tmp;
string_f(vars, name, tmp);
@ -710,7 +742,8 @@ void double_f(std::unordered_map<std::string, std::string> &vars, const std::str
input = val;
}
void double_between_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, double &input, const std::pair<double, double> &range) {
void
double_between_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, double &input, const std::pair<double, double> &range) {
double temp = input;
double_f(vars, name, temp);
@ -721,7 +754,8 @@ void double_between_f(std::unordered_map<std::string, std::string> &vars, const
}
}
void list_string_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<std::string> &input) {
void
list_string_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<std::string> &input) {
std::string string;
string_f(vars, name, string);
@ -763,7 +797,8 @@ void list_string_f(std::unordered_map<std::string, std::string> &vars, const std
}
}
void list_prep_cmd_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<prep_cmd_t> &input) {
void
list_prep_cmd_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<prep_cmd_t> &input) {
std::string string;
string_f(vars, name, string);
@ -790,7 +825,8 @@ void list_prep_cmd_f(std::unordered_map<std::string, std::string> &vars, const s
}
}
void list_int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<int> &input) {
void
list_int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::vector<int> &input) {
std::vector<std::string> list;
list_string_f(vars, name, list);
@ -815,7 +851,8 @@ void list_int_f(std::unordered_map<std::string, std::string> &vars, const std::s
}
}
void map_int_int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::unordered_map<int, int> &input) {
void
map_int_int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::unordered_map<int, int> &input) {
std::vector<int> list;
list_int_f(vars, name, list);
@ -834,7 +871,8 @@ void map_int_int_f(std::unordered_map<std::string, std::string> &vars, const std
}
}
int apply_flags(const char *line) {
int
apply_flags(const char *line) {
int ret = 0;
while (*line != '\0') {
switch (*line) {
@ -861,7 +899,8 @@ int apply_flags(const char *line) {
return ret;
}
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
void
apply_config(std::unordered_map<std::string, std::string> &&vars) {
if (!fs::exists(stream.file_apps.c_str())) {
fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps);
}
@ -1047,7 +1086,8 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
}
}
int parse(int argc, char *argv[]) {
int
parse(int argc, char *argv[]) {
std::unordered_map<std::string, std::string> cmd_vars;
for (auto x = 1; x < argc; ++x) {

View file

@ -119,8 +119,10 @@ enum flag_e : std::size_t {
}
struct prep_cmd_t {
prep_cmd_t(std::string &&do_cmd, std::string &&undo_cmd) : do_cmd(std::move(do_cmd)), undo_cmd(std::move(undo_cmd)) {}
explicit prep_cmd_t(std::string &&do_cmd) : do_cmd(std::move(do_cmd)) {}
prep_cmd_t(std::string &&do_cmd, std::string &&undo_cmd):
do_cmd(std::move(do_cmd)), undo_cmd(std::move(undo_cmd)) {}
explicit prep_cmd_t(std::string &&do_cmd):
do_cmd(std::move(do_cmd)) {}
std::string do_cmd;
std::string undo_cmd;
};
@ -155,7 +157,9 @@ extern nvhttp_t nvhttp;
extern input_t input;
extern sunshine_t sunshine;
int parse(int argc, char *argv[]);
std::unordered_map<std::string, std::string> parse_config(const std::string_view &file_content);
int
parse(int argc, char *argv[]);
std::unordered_map<std::string, std::string>
parse_config(const std::string_view &file_content);
} // namespace config
#endif

View file

@ -52,7 +52,8 @@ enum class op_e {
REMOVE
};
void print_req(const req_https_t &request) {
void
print_req(const req_https_t &request) {
BOOST_LOG(debug) << "METHOD :: "sv << request->method;
BOOST_LOG(debug) << "DESTINATION :: "sv << request->path;
@ -69,7 +70,8 @@ void print_req(const req_https_t &request) {
BOOST_LOG(debug) << " [--] "sv;
}
void send_unauthorized(resp_https_t response, req_https_t request) {
void
send_unauthorized(resp_https_t response, req_https_t request) {
auto address = request->remote_endpoint().address().to_string();
BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
const SimpleWeb::CaseInsensitiveMultimap headers {
@ -78,7 +80,8 @@ void send_unauthorized(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::client_error_unauthorized, headers);
}
void send_redirect(resp_https_t response, req_https_t request, const char *path) {
void
send_redirect(resp_https_t response, req_https_t request, const char *path) {
auto address = request->remote_endpoint().address().to_string();
BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
const SimpleWeb::CaseInsensitiveMultimap headers {
@ -87,7 +90,8 @@ void send_redirect(resp_https_t response, req_https_t request, const char *path)
response->write(SimpleWeb::StatusCode::redirection_temporary_redirect, headers);
}
bool authenticate(resp_https_t response, req_https_t request) {
bool
authenticate(resp_https_t response, req_https_t request) {
auto address = request->remote_endpoint().address().to_string();
auto ip_type = net::from_address(address);
@ -132,7 +136,8 @@ bool authenticate(resp_https_t response, req_https_t request) {
return true;
}
void not_found(resp_https_t response, req_https_t request) {
void
not_found(resp_https_t response, req_https_t request) {
pt::ptree tree;
tree.put("root.<xmlattr>.status_code", 404);
@ -146,7 +151,8 @@ void not_found(resp_https_t response, req_https_t request) {
}
// todo - combine these functions into a single function that accepts the page, i.e "index", "pin", "apps"
void getIndexPage(resp_https_t response, req_https_t request) {
void
getIndexPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -156,7 +162,8 @@ void getIndexPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getPinPage(resp_https_t response, req_https_t request) {
void
getPinPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -166,7 +173,8 @@ void getPinPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getAppsPage(resp_https_t response, req_https_t request) {
void
getAppsPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -179,7 +187,8 @@ void getAppsPage(resp_https_t response, req_https_t request) {
response->write(header + content, headers);
}
void getClientsPage(resp_https_t response, req_https_t request) {
void
getClientsPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -189,7 +198,8 @@ void getClientsPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getConfigPage(resp_https_t response, req_https_t request) {
void
getConfigPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -199,7 +209,8 @@ void getConfigPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getPasswordPage(resp_https_t response, req_https_t request) {
void
getPasswordPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -209,7 +220,8 @@ void getPasswordPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getWelcomePage(resp_https_t response, req_https_t request) {
void
getWelcomePage(resp_https_t response, req_https_t request) {
print_req(request);
if (!config::sunshine.username.empty()) {
send_redirect(response, request, "/");
@ -220,7 +232,8 @@ void getWelcomePage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getTroubleshootingPage(resp_https_t response, req_https_t request) {
void
getTroubleshootingPage(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -230,7 +243,8 @@ void getTroubleshootingPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
void getFaviconImage(resp_https_t response, req_https_t request) {
void
getFaviconImage(resp_https_t response, req_https_t request) {
// todo - combine function with getSunshineLogoImage and possibly getNodeModules
// todo - use mime_types map
print_req(request);
@ -241,7 +255,8 @@ void getFaviconImage(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
}
void getSunshineLogoImage(resp_https_t response, req_https_t request) {
void
getSunshineLogoImage(resp_https_t response, req_https_t request) {
// todo - combine function with getFaviconImage and possibly getNodeModules
// todo - use mime_types map
print_req(request);
@ -252,12 +267,14 @@ void getSunshineLogoImage(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::success_ok, in, headers);
}
bool isChildPath(fs::path const &base, fs::path const &query) {
bool
isChildPath(fs::path const &base, fs::path const &query) {
auto relPath = fs::relative(base, query);
return *(relPath.begin()) != fs::path("..");
}
void getNodeModules(resp_https_t response, req_https_t request) {
void
getNodeModules(resp_https_t response, req_https_t request) {
print_req(request);
fs::path webDirPath(WEB_DIR);
fs::path nodeModulesPath(webDirPath / "node_modules");
@ -290,7 +307,8 @@ void getNodeModules(resp_https_t response, req_https_t request) {
}
}
void getApps(resp_https_t response, req_https_t request) {
void
getApps(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -299,7 +317,8 @@ void getApps(resp_https_t response, req_https_t request) {
response->write(content);
}
void getLogs(resp_https_t response, req_https_t request) {
void
getLogs(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -310,7 +329,8 @@ void getLogs(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::success_ok, content, headers);
}
void saveApp(resp_https_t response, req_https_t request) {
void
saveApp(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -380,7 +400,8 @@ void saveApp(resp_https_t response, req_https_t request) {
proc::refresh(config::stream.file_apps);
}
void deleteApp(resp_https_t response, req_https_t request) {
void
deleteApp(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -428,7 +449,8 @@ void deleteApp(resp_https_t response, req_https_t request) {
proc::refresh(config::stream.file_apps);
}
void uploadCover(resp_https_t response, req_https_t request) {
void
uploadCover(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
std::stringstream ss;
@ -489,7 +511,8 @@ void uploadCover(resp_https_t response, req_https_t request) {
outputTree.put("path", path);
}
void getConfig(resp_https_t response, req_https_t request) {
void
getConfig(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -514,7 +537,8 @@ void getConfig(resp_https_t response, req_https_t request) {
}
}
void saveConfig(resp_https_t response, req_https_t request) {
void
saveConfig(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -549,7 +573,8 @@ void saveConfig(resp_https_t response, req_https_t request) {
}
}
void restart(resp_https_t response, req_https_t request) {
void
restart(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -580,7 +605,8 @@ void restart(resp_https_t response, req_https_t request) {
outputTree.put("status", true);
}
void savePassword(resp_https_t response, req_https_t request) {
void
savePassword(resp_https_t response, req_https_t request) {
if (!config::sunshine.username.empty() && !authenticate(response, request)) return;
print_req(request);
@ -637,7 +663,8 @@ void savePassword(resp_https_t response, req_https_t request) {
}
}
void savePin(resp_https_t response, req_https_t request) {
void
savePin(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -667,7 +694,8 @@ void savePin(resp_https_t response, req_https_t request) {
}
}
void unpairAll(resp_https_t response, req_https_t request) {
void
unpairAll(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -683,7 +711,8 @@ void unpairAll(resp_https_t response, req_https_t request) {
outputTree.put("status", true);
}
void closeApp(resp_https_t response, req_https_t request) {
void
closeApp(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
print_req(request);
@ -700,7 +729,8 @@ void closeApp(resp_https_t response, req_https_t request) {
outputTree.put("status", true);
}
void start() {
void
start() {
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
auto port_https = map_port(PORT_HTTPS);

View file

@ -10,10 +10,10 @@
#define WEB_DIR SUNSHINE_ASSETS_DIR "/web/"
namespace confighttp {
constexpr auto PORT_HTTPS = 1;
void start();
void
start();
} // namespace confighttp
// mime types map

View file

@ -6,15 +6,18 @@
namespace crypto {
using asn1_string_t = util::safe_ptr<ASN1_STRING, ASN1_STRING_free>;
cert_chain_t::cert_chain_t() : _certs {}, _cert_ctx { X509_STORE_CTX_new() } {}
void cert_chain_t::add(x509_t &&cert) {
cert_chain_t::cert_chain_t():
_certs {}, _cert_ctx { X509_STORE_CTX_new() } {}
void
cert_chain_t::add(x509_t &&cert) {
x509_store_t x509_store { X509_STORE_new() };
X509_STORE_add_cert(x509_store.get(), cert.get());
_certs.emplace_back(std::make_pair(std::move(cert), std::move(x509_store)));
}
static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {
static int
openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {
int err_code = X509_STORE_CTX_get_error(ctx);
switch (err_code) {
@ -39,7 +42,8 @@ static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {
*
* To circumvent this, x509_store_t instance will be created for each instance of the certificates.
*/
const char *cert_chain_t::verify(x509_t::element_type *cert) {
const char *
cert_chain_t::verify(x509_t::element_type *cert) {
int err_code = 0;
for (auto &[_, x509_store] : _certs) {
auto fg = util::fail_guard([this]() {
@ -72,7 +76,8 @@ const char *cert_chain_t::verify(x509_t::element_type *cert) {
namespace cipher {
static int init_decrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
static int
init_decrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
ctx.reset(EVP_CIPHER_CTX_new());
if (!ctx) {
@ -95,7 +100,8 @@ static int init_decrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool paddi
return 0;
}
static int init_encrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
static int
init_encrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
ctx.reset(EVP_CIPHER_CTX_new());
// Gen 7 servers use 128-bit AES ECB
@ -115,7 +121,8 @@ static int init_encrypt_gcm(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool paddi
return 0;
}
static int init_encrypt_cbc(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
static int
init_encrypt_cbc(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool padding) {
ctx.reset(EVP_CIPHER_CTX_new());
// Gen 7 servers use 128-bit AES ECB
@ -128,7 +135,8 @@ static int init_encrypt_cbc(cipher_ctx_t &ctx, aes_t *key, aes_t *iv, bool paddi
return 0;
}
int gcm_t::decrypt(const std::string_view &tagged_cipher, std::vector<std::uint8_t> &plaintext, aes_t *iv) {
int
gcm_t::decrypt(const std::string_view &tagged_cipher, std::vector<std::uint8_t> &plaintext, aes_t *iv) {
if (!decrypt_ctx && init_decrypt_gcm(decrypt_ctx, &key, iv, padding)) {
return -1;
}
@ -162,7 +170,8 @@ int gcm_t::decrypt(const std::string_view &tagged_cipher, std::vector<std::uint8
return 0;
}
int gcm_t::encrypt(const std::string_view &plaintext, std::uint8_t *tagged_cipher, aes_t *iv) {
int
gcm_t::encrypt(const std::string_view &plaintext, std::uint8_t *tagged_cipher, aes_t *iv) {
if (!encrypt_ctx && init_encrypt_gcm(encrypt_ctx, &key, iv, padding)) {
return -1;
}
@ -196,7 +205,8 @@ int gcm_t::encrypt(const std::string_view &plaintext, std::uint8_t *tagged_ciphe
return len + size;
}
int ecb_t::decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext) {
int
ecb_t::decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext) {
int len;
auto fg = util::fail_guard([this]() {
@ -225,7 +235,8 @@ int ecb_t::decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &pl
return 0;
}
int ecb_t::encrypt(const std::string_view &plaintext, std::vector<std::uint8_t> &cipher) {
int
ecb_t::encrypt(const std::string_view &plaintext, std::vector<std::uint8_t> &cipher) {
auto fg = util::fail_guard([this]() {
EVP_CIPHER_CTX_reset(encrypt_ctx.get());
});
@ -255,7 +266,8 @@ int ecb_t::encrypt(const std::string_view &plaintext, std::vector<std::uint8_t>
return 0;
}
int cbc_t::encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_t *iv) {
int
cbc_t::encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_t *iv) {
if (!encrypt_ctx && init_encrypt_cbc(encrypt_ctx, &key, iv, padding)) {
return -1;
}
@ -282,18 +294,19 @@ int cbc_t::encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_
return size + len;
}
ecb_t::ecb_t(const aes_t &key, bool padding)
: cipher_t { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_new(), key, padding } {}
ecb_t::ecb_t(const aes_t &key, bool padding):
cipher_t { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_new(), key, padding } {}
cbc_t::cbc_t(const aes_t &key, bool padding)
: cipher_t { nullptr, nullptr, key, padding } {}
cbc_t::cbc_t(const aes_t &key, bool padding):
cipher_t { nullptr, nullptr, key, padding } {}
gcm_t::gcm_t(const crypto::aes_t &key, bool padding)
: cipher_t { nullptr, nullptr, key, padding } {}
gcm_t::gcm_t(const crypto::aes_t &key, bool padding):
cipher_t { nullptr, nullptr, key, padding } {}
} // namespace cipher
aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &pin) {
aes_t
gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &pin) {
aes_t key;
std::string salt_pin;
@ -309,13 +322,15 @@ aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &p
return key;
}
sha256_t hash(const std::string_view &plaintext) {
sha256_t
hash(const std::string_view &plaintext) {
sha256_t hsh;
EVP_Digest(plaintext.data(), plaintext.size(), hsh.data(), nullptr, EVP_sha256(), nullptr);
return hsh;
}
x509_t x509(const std::string_view &x) {
x509_t
x509(const std::string_view &x) {
bio_t io { BIO_new(BIO_s_mem()) };
BIO_write(io.get(), x.data(), x.size());
@ -326,7 +341,8 @@ x509_t x509(const std::string_view &x) {
return p;
}
pkey_t pkey(const std::string_view &k) {
pkey_t
pkey(const std::string_view &k) {
bio_t io { BIO_new(BIO_s_mem()) };
BIO_write(io.get(), k.data(), k.size());
@ -337,7 +353,8 @@ pkey_t pkey(const std::string_view &k) {
return p;
}
std::string pem(x509_t &x509) {
std::string
pem(x509_t &x509) {
bio_t bio { BIO_new(BIO_s_mem()) };
PEM_write_bio_X509(bio.get(), x509.get());
@ -347,7 +364,8 @@ std::string pem(x509_t &x509) {
return { mem_ptr->data, mem_ptr->length };
}
std::string pem(pkey_t &pkey) {
std::string
pem(pkey_t &pkey) {
bio_t bio { BIO_new(BIO_s_mem()) };
PEM_write_bio_PrivateKey(bio.get(), pkey.get(), nullptr, nullptr, 0, nullptr, nullptr);
@ -357,7 +375,8 @@ std::string pem(pkey_t &pkey) {
return { mem_ptr->data, mem_ptr->length };
}
std::string_view signature(const x509_t &x) {
std::string_view
signature(const x509_t &x) {
// X509_ALGOR *_ = nullptr;
const ASN1_BIT_STRING *asn1 = nullptr;
@ -366,7 +385,8 @@ std::string_view signature(const x509_t &x) {
return { (const char *) asn1->data, (std::size_t) asn1->length };
}
std::string rand(std::size_t bytes) {
std::string
rand(std::size_t bytes) {
std::string r;
r.resize(bytes);
@ -375,7 +395,8 @@ std::string rand(std::size_t bytes) {
return r;
}
std::vector<uint8_t> sign(const pkey_t &pkey, const std::string_view &data, const EVP_MD *md) {
std::vector<uint8_t>
sign(const pkey_t &pkey, const std::string_view &data, const EVP_MD *md) {
md_ctx_t ctx { EVP_MD_CTX_create() };
if (EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey.get()) != 1) {
@ -398,7 +419,8 @@ std::vector<uint8_t> sign(const pkey_t &pkey, const std::string_view &data, cons
return digest;
}
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits) {
creds_t
gen_creds(const std::string_view &cn, std::uint32_t key_bits) {
x509_t x509 { X509_new() };
pkey_ctx_t ctx { EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr) };
pkey_t pkey;
@ -443,11 +465,13 @@ creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits) {
return { pem(x509), pem(pkey) };
}
std::vector<uint8_t> sign256(const pkey_t &pkey, const std::string_view &data) {
std::vector<uint8_t>
sign256(const pkey_t &pkey, const std::string_view &data) {
return sign(pkey, data, EVP_sha256());
}
bool verify(const x509_t &x509, const std::string_view &data, const std::string_view &signature, const EVP_MD *md) {
bool
verify(const x509_t &x509, const std::string_view &data, const std::string_view &signature, const EVP_MD *md) {
auto pkey = X509_get_pubkey(x509.get());
md_ctx_t ctx { EVP_MD_CTX_create() };
@ -467,15 +491,18 @@ bool verify(const x509_t &x509, const std::string_view &data, const std::string_
return true;
}
bool verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature) {
bool
verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature) {
return verify(x509, data, signature, EVP_sha256());
}
void md_ctx_destroy(EVP_MD_CTX *ctx) {
void
md_ctx_destroy(EVP_MD_CTX *ctx) {
EVP_MD_CTX_destroy(ctx);
}
std::string rand_alphabet(std::size_t bytes, const std::string_view &alphabet) {
std::string
rand_alphabet(std::size_t bytes, const std::string_view &alphabet) {
auto value = rand(bytes);
for (std::size_t i = 0; i != value.size(); ++i) {

View file

@ -18,7 +18,8 @@ struct creds_t {
};
constexpr std::size_t digest_size = 256;
void md_ctx_destroy(EVP_MD_CTX *);
void
md_ctx_destroy(EVP_MD_CTX *);
using sha256_t = std::array<std::uint8_t, SHA256_DIGEST_LENGTH>;
@ -33,33 +34,47 @@ using pkey_t = util::safe_ptr<EVP_PKEY, EVP_PKEY_free>;
using pkey_ctx_t = util::safe_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
using bignum_t = util::safe_ptr<BIGNUM, BN_free>;
sha256_t hash(const std::string_view &plaintext);
sha256_t
hash(const std::string_view &plaintext);
aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &pin);
aes_t
gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &pin);
x509_t x509(const std::string_view &x);
pkey_t pkey(const std::string_view &k);
std::string pem(x509_t &x509);
std::string pem(pkey_t &pkey);
x509_t
x509(const std::string_view &x);
pkey_t
pkey(const std::string_view &k);
std::string
pem(x509_t &x509);
std::string
pem(pkey_t &pkey);
std::vector<uint8_t> sign256(const pkey_t &pkey, const std::string_view &data);
bool verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature);
std::vector<uint8_t>
sign256(const pkey_t &pkey, const std::string_view &data);
bool
verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature);
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits);
creds_t
gen_creds(const std::string_view &cn, std::uint32_t key_bits);
std::string_view signature(const x509_t &x);
std::string_view
signature(const x509_t &x);
std::string rand(std::size_t bytes);
std::string rand_alphabet(std::size_t bytes,
std::string
rand(std::size_t bytes);
std::string
rand_alphabet(std::size_t bytes,
const std::string_view &alphabet = std::string_view { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!%&()=-" });
class cert_chain_t {
public:
KITTY_DECL_CONSTR(cert_chain_t)
void add(x509_t &&cert);
void
add(x509_t &&cert);
const char *verify(x509_t::element_type *cert);
const char *
verify(x509_t::element_type *cert);
private:
std::vector<std::pair<x509_t, x509_store_t>> _certs;
@ -68,7 +83,8 @@ private:
namespace cipher {
constexpr std::size_t tag_size = 16;
constexpr std::size_t round_to_pkcs7_padded(std::size_t size) {
constexpr std::size_t
round_to_pkcs7_padded(std::size_t size) {
return ((size + 15) / 16) * 16;
}
@ -86,19 +102,23 @@ class ecb_t : public cipher_t {
public:
ecb_t() = default;
ecb_t(ecb_t &&) noexcept = default;
ecb_t &operator=(ecb_t &&) noexcept = default;
ecb_t &
operator=(ecb_t &&) noexcept = default;
ecb_t(const aes_t &key, bool padding = true);
int encrypt(const std::string_view &plaintext, std::vector<std::uint8_t> &cipher);
int decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext);
int
encrypt(const std::string_view &plaintext, std::vector<std::uint8_t> &cipher);
int
decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext);
};
class gcm_t: public cipher_t {
public:
gcm_t() = default;
gcm_t(gcm_t &&) noexcept = default;
gcm_t &operator=(gcm_t &&) noexcept = default;
gcm_t &
operator=(gcm_t &&) noexcept = default;
gcm_t(const crypto::aes_t &key, bool padding = true);
@ -108,16 +128,19 @@ public:
* return -1 on error
* return bytes written on success
*/
int encrypt(const std::string_view &plaintext, std::uint8_t *tagged_cipher, aes_t *iv);
int
encrypt(const std::string_view &plaintext, std::uint8_t *tagged_cipher, aes_t *iv);
int decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext, aes_t *iv);
int
decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext, aes_t *iv);
};
class cbc_t: public cipher_t {
public:
cbc_t() = default;
cbc_t(cbc_t &&) noexcept = default;
cbc_t &operator=(cbc_t &&) noexcept = default;
cbc_t &
operator=(cbc_t &&) noexcept = default;
cbc_t(const crypto::aes_t &key, bool padding = true);
@ -127,7 +150,8 @@ public:
* return -1 on error
* return bytes written on success
*/
int encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_t *iv);
int
encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_t *iv);
};
} // namespace cipher
} // namespace crypto

View file

@ -31,14 +31,17 @@ using namespace std::literals;
namespace fs = std::filesystem;
namespace pt = boost::property_tree;
int reload_user_creds(const std::string &file);
bool user_creds_exist(const std::string &file);
int
reload_user_creds(const std::string &file);
bool
user_creds_exist(const std::string &file);
std::string unique_id;
net::net_e origin_pin_allowed;
net::net_e origin_web_ui_allowed;
int init() {
int
init() {
bool clean_slate = config::sunshine.flags[config::flag::FRESH_STATE];
origin_pin_allowed = net::from_enum_string(config::nvhttp.origin_pin_allowed);
origin_web_ui_allowed = net::from_enum_string(config::nvhttp.origin_web_ui_allowed);
@ -64,7 +67,8 @@ int init() {
return 0;
}
int save_user_creds(const std::string &file, const std::string &username, const std::string &password, bool run_our_mouth) {
int
save_user_creds(const std::string &file, const std::string &username, const std::string &password, bool run_our_mouth) {
pt::ptree outputTree;
if (fs::exists(file)) {
@ -93,7 +97,8 @@ int save_user_creds(const std::string &file, const std::string &username, const
return 0;
}
bool user_creds_exist(const std::string &file) {
bool
user_creds_exist(const std::string &file) {
if (!fs::exists(file)) {
return false;
}
@ -112,7 +117,8 @@ bool user_creds_exist(const std::string &file) {
return false;
}
int reload_user_creds(const std::string &file) {
int
reload_user_creds(const std::string &file) {
pt::ptree inputTree;
try {
pt::read_json(file, inputTree);
@ -127,7 +133,8 @@ int reload_user_creds(const std::string &file) {
return 0;
}
int create_creds(const std::string &pkey, const std::string &cert) {
int
create_creds(const std::string &pkey, const std::string &cert) {
fs::path pkey_path = pkey;
fs::path cert_path = cert;
@ -182,7 +189,8 @@ int create_creds(const std::string &pkey, const std::string &cert) {
return 0;
}
bool download_file(const std::string &url, const std::string &file) {
bool
download_file(const std::string &url, const std::string &file) {
CURL *curl = curl_easy_init();
if (!curl) {
BOOST_LOG(error) << "Couldn't create CURL instance";
@ -209,7 +217,8 @@ bool download_file(const std::string &url, const std::string &file) {
return result == CURLE_OK;
}
std::string url_escape(const std::string &url) {
std::string
url_escape(const std::string &url) {
CURL *curl = curl_easy_init();
char *string = curl_easy_escape(curl, url.c_str(), url.length());
std::string result(string);
@ -218,7 +227,8 @@ std::string url_escape(const std::string &url) {
return result;
}
std::string url_get_host(const std::string &url) {
std::string
url_get_host(const std::string &url) {
CURLU *curlu = curl_url();
curl_url_set(curlu, CURLUPART_URL, url.c_str(), url.length());
char *host;

View file

@ -3,18 +3,25 @@
namespace http {
int init();
int create_creds(const std::string &pkey, const std::string &cert);
int save_user_creds(
int
init();
int
create_creds(const std::string &pkey, const std::string &cert);
int
save_user_creds(
const std::string &file,
const std::string &username,
const std::string &password,
bool run_our_mouth = false);
int reload_user_creds(const std::string &file);
bool download_file(const std::string &url, const std::string &file);
std::string url_escape(const std::string &url);
std::string url_get_host(const std::string &url);
int
reload_user_creds(const std::string &file);
bool
download_file(const std::string &url, const std::string &file);
std::string
url_escape(const std::string &url);
std::string
url_get_host(const std::string &url);
extern std::string unique_id;
extern net::net_e origin_pin_allowed;

View file

@ -41,7 +41,8 @@ enum class button_state_e {
};
template <std::size_t N>
int alloc_id(std::bitset<N> &gamepad_mask) {
int
alloc_id(std::bitset<N> &gamepad_mask) {
for (int x = 0; x < gamepad_mask.size(); ++x) {
if (!gamepad_mask[x]) {
gamepad_mask[x] = true;
@ -53,7 +54,8 @@ int alloc_id(std::bitset<N> &gamepad_mask) {
}
template <std::size_t N>
void free_id(std::bitset<N> &gamepad_mask, int id) {
void
free_id(std::bitset<N> &gamepad_mask, int id) {
gamepad_mask[id] = false;
}
@ -64,14 +66,16 @@ static std::array<std::uint8_t, 5> mouse_press {};
static platf::input_t platf_input;
static std::bitset<platf::MAX_GAMEPADS> gamepadMask {};
void free_gamepad(platf::input_t &platf_input, int id) {
void
free_gamepad(platf::input_t &platf_input, int id) {
platf::gamepad(platf_input, id, platf::gamepad_state_t {});
platf::free_gamepad(platf_input, id);
free_id(gamepadMask, id);
}
struct gamepad_t {
gamepad_t() : gamepad_state {}, back_timeout_id {}, id { -1 }, back_button_state { button_state_e::NONE } {}
gamepad_t():
gamepad_state {}, back_timeout_id {}, id { -1 }, back_button_state { button_state_e::NONE } {}
~gamepad_t() {
if (id >= 0) {
task_pool.push([id = this->id]() {
@ -105,8 +109,8 @@ struct input_t {
input_t(
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event,
platf::rumble_queue_t rumble_queue)
: shortcutFlags {},
platf::rumble_queue_t rumble_queue):
shortcutFlags {},
active_gamepad_state {},
gamepads(MAX_GAMEPADS),
touch_port_event { std::move(touch_port_event) },
@ -135,7 +139,8 @@ struct input_t {
* On nothing
* return 0
*/
inline int apply_shortcut(short keyCode) {
inline int
apply_shortcut(short keyCode) {
constexpr auto VK_F1 = 0x70;
constexpr auto VK_F13 = 0x7C;
@ -155,7 +160,8 @@ inline int apply_shortcut(short keyCode) {
return 0;
}
void print(PNV_REL_MOUSE_MOVE_PACKET packet) {
void
print(PNV_REL_MOUSE_MOVE_PACKET packet) {
BOOST_LOG(debug)
<< "--begin relative mouse move packet--"sv << std::endl
<< "deltaX ["sv << util::endian::big(packet->deltaX) << ']' << std::endl
@ -163,7 +169,8 @@ void print(PNV_REL_MOUSE_MOVE_PACKET packet) {
<< "--end relative mouse move packet--"sv;
}
void print(PNV_ABS_MOUSE_MOVE_PACKET packet) {
void
print(PNV_ABS_MOUSE_MOVE_PACKET packet) {
BOOST_LOG(debug)
<< "--begin absolute mouse move packet--"sv << std::endl
<< "x ["sv << util::endian::big(packet->x) << ']' << std::endl
@ -173,7 +180,8 @@ void print(PNV_ABS_MOUSE_MOVE_PACKET packet) {
<< "--end absolute mouse move packet--"sv;
}
void print(PNV_MOUSE_BUTTON_PACKET packet) {
void
print(PNV_MOUSE_BUTTON_PACKET packet) {
BOOST_LOG(debug)
<< "--begin mouse button packet--"sv << std::endl
<< "action ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl
@ -181,21 +189,24 @@ void print(PNV_MOUSE_BUTTON_PACKET packet) {
<< "--end mouse button packet--"sv;
}
void print(PNV_SCROLL_PACKET packet) {
void
print(PNV_SCROLL_PACKET packet) {
BOOST_LOG(debug)
<< "--begin mouse scroll packet--"sv << std::endl
<< "scrollAmt1 ["sv << util::endian::big(packet->scrollAmt1) << ']' << std::endl
<< "--end mouse scroll packet--"sv;
}
void print(PSS_HSCROLL_PACKET packet) {
void
print(PSS_HSCROLL_PACKET packet) {
BOOST_LOG(debug)
<< "--begin mouse hscroll packet--"sv << std::endl
<< "scrollAmount ["sv << util::endian::big(packet->scrollAmount) << ']' << std::endl
<< "--end mouse hscroll packet--"sv;
}
void print(PNV_KEYBOARD_PACKET packet) {
void
print(PNV_KEYBOARD_PACKET packet) {
BOOST_LOG(debug)
<< "--begin keyboard packet--"sv << std::endl
<< "keyAction ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl
@ -205,7 +216,8 @@ void print(PNV_KEYBOARD_PACKET packet) {
<< "--end keyboard packet--"sv;
}
void print(PNV_UNICODE_PACKET packet) {
void
print(PNV_UNICODE_PACKET packet) {
std::string text(packet->text, util::endian::big(packet->header.size) - sizeof(packet->header.magic));
BOOST_LOG(debug)
<< "--begin unicode packet--"sv << std::endl
@ -213,7 +225,8 @@ void print(PNV_UNICODE_PACKET packet) {
<< "--end unicode packet--"sv;
}
void print(PNV_MULTI_CONTROLLER_PACKET packet) {
void
print(PNV_MULTI_CONTROLLER_PACKET packet) {
// Moonlight spams controller packet even when not necessary
BOOST_LOG(verbose)
<< "--begin controller packet--"sv << std::endl
@ -229,7 +242,8 @@ void print(PNV_MULTI_CONTROLLER_PACKET packet) {
<< "--end controller packet--"sv;
}
void print(void *payload) {
void
print(void *payload) {
auto header = (PNV_INPUT_HEADER) payload;
switch (util::endian::little(header->magic)) {
@ -262,7 +276,8 @@ void print(void *payload) {
}
}
void passthrough(std::shared_ptr<input_t> &input, PNV_REL_MOUSE_MOVE_PACKET packet) {
void
passthrough(std::shared_ptr<input_t> &input, PNV_REL_MOUSE_MOVE_PACKET packet) {
if (!config::input.mouse) {
return;
}
@ -271,7 +286,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_REL_MOUSE_MOVE_PACKET pack
platf::move_mouse(platf_input, util::endian::big(packet->deltaX), util::endian::big(packet->deltaY));
}
void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET packet) {
void
passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET packet) {
if (!config::input.mouse) {
return;
}
@ -320,7 +336,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET pack
platf::abs_mouse(platf_input, abs_port, (x - offsetX) * touch_port.scalar_inv, (y - offsetY) * touch_port.scalar_inv);
}
void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
void
passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
if (!config::input.mouse) {
return;
}
@ -382,7 +399,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
platf::button_mouse(platf_input, button, release);
}
short map_keycode(short keycode) {
short
map_keycode(short keycode) {
auto it = config::input.keybindings.find(keycode);
if (it != std::end(config::input.keybindings)) {
return it->second;
@ -394,7 +412,8 @@ short map_keycode(short keycode) {
/**
* Update flags for keyboard shortcut combo's
*/
inline void update_shortcutFlags(int *flags, short keyCode, bool release) {
inline void
update_shortcutFlags(int *flags, short keyCode, bool release) {
switch (keyCode) {
case VKEY_SHIFT:
case VKEY_LSHIFT:
@ -429,7 +448,8 @@ inline void update_shortcutFlags(int *flags, short keyCode, bool release) {
}
}
void repeat_key(short key_code) {
void
repeat_key(short key_code) {
// If key no longer pressed, stop repeating
if (!key_press[key_code]) {
key_press_repeat_id = nullptr;
@ -441,7 +461,8 @@ void repeat_key(short key_code) {
key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code).task_id;
}
void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
void
passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
if (!config::input.keyboard) {
return;
}
@ -482,7 +503,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
platf::keyboard(platf_input, map_keycode(keyCode), release);
}
void passthrough(PNV_SCROLL_PACKET packet) {
void
passthrough(PNV_SCROLL_PACKET packet) {
if (!config::input.mouse) {
return;
}
@ -490,7 +512,8 @@ void passthrough(PNV_SCROLL_PACKET packet) {
platf::scroll(platf_input, util::endian::big(packet->scrollAmt1));
}
void passthrough(PSS_HSCROLL_PACKET packet) {
void
passthrough(PSS_HSCROLL_PACKET packet) {
if (!config::input.mouse) {
return;
}
@ -498,7 +521,8 @@ void passthrough(PSS_HSCROLL_PACKET packet) {
platf::hscroll(platf_input, util::endian::big(packet->scrollAmount));
}
void passthrough(PNV_UNICODE_PACKET packet) {
void
passthrough(PNV_UNICODE_PACKET packet) {
if (!config::input.keyboard) {
return;
}
@ -507,7 +531,8 @@ void passthrough(PNV_UNICODE_PACKET packet) {
platf::unicode(platf_input, packet->text, size);
}
int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state, const platf::rumble_queue_t &rumble_queue) {
int
updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state, const platf::rumble_queue_t &rumble_queue) {
auto xorGamepadMask = old_state ^ new_state;
if (!xorGamepadMask) {
return 0;
@ -548,7 +573,8 @@ int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std
return 0;
}
void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET packet) {
void
passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET packet) {
if (!config::input.controller) {
return;
}
@ -650,7 +676,8 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET pa
gamepad.gamepad_state = gamepad_state;
}
void passthrough_helper(std::shared_ptr<input_t> input, std::vector<std::uint8_t> &&input_data) {
void
passthrough_helper(std::shared_ptr<input_t> input, std::vector<std::uint8_t> &&input_data) {
void *payload = input_data.data();
auto header = (PNV_INPUT_HEADER) payload;
@ -684,11 +711,13 @@ void passthrough_helper(std::shared_ptr<input_t> input, std::vector<std::uint8_t
}
}
void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data) {
void
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data) {
task_pool.push(passthrough_helper, input, move_by_copy_util::cmove(input_data));
}
void reset(std::shared_ptr<input_t> &input) {
void
reset(std::shared_ptr<input_t> &input) {
task_pool.cancel(key_press_repeat_id);
task_pool.cancel(input->mouse_left_button_timeout);
@ -715,13 +744,15 @@ public:
}
};
[[nodiscard]] std::unique_ptr<platf::deinit_t> init() {
[[nodiscard]] std::unique_ptr<platf::deinit_t>
init() {
platf_input = platf::input();
return std::make_unique<deinit_t>();
}
std::shared_ptr<input_t> alloc(safe::mail_t mail) {
std::shared_ptr<input_t>
alloc(safe::mail_t mail) {
auto input = std::make_shared<input_t>(
mail->event<input::touch_port_t>(mail::touch_port),
mail->queue<platf::rumble_t>(mail::rumble));

View file

@ -11,14 +11,18 @@
namespace input {
struct input_t;
void print(void *input);
void reset(std::shared_ptr<input_t> &input);
void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data);
void
print(void *input);
void
reset(std::shared_ptr<input_t> &input);
void
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data);
[[nodiscard]] std::unique_ptr<platf::deinit_t>
init();
[[nodiscard]] std::unique_ptr<platf::deinit_t> init();
std::shared_ptr<input_t> alloc(safe::mail_t mail);
std::shared_ptr<input_t>
alloc(safe::mail_t mail);
struct touch_port_t: public platf::touch_port_t {
int env_width, env_height;

View file

@ -55,7 +55,8 @@ using text_sink = bl::sinks::asynchronous_sink<bl::sinks::text_ostream_backend>;
boost::shared_ptr<text_sink> sink;
struct NoDelete {
void operator()(void *) {}
void
operator()(void *) {}
};
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
@ -69,7 +70,8 @@ BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
* print_help("sunshine");
* ```
*/
void print_help(const char *name) {
void
print_help(const char *name) {
std::cout
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
@ -90,20 +92,21 @@ void print_help(const char *name) {
}
namespace help {
int entry(const char *name, int argc, char *argv[]) {
int
entry(const char *name, int argc, char *argv[]) {
print_help(name);
return 0;
}
} // namespace help
namespace version {
int entry(const char *name, int argc, char *argv[]) {
int
entry(const char *name, int argc, char *argv[]) {
std::cout << PROJECT_NAME << " version: v" << PROJECT_VER << std::endl;
return 0;
}
} // namespace version
/**
* @brief Flush the log.
*
@ -112,24 +115,28 @@ int entry(const char *name, int argc, char *argv[]) {
* log_flush();
* ```
*/
void log_flush() {
void
log_flush() {
sink->flush();
}
std::map<int, std::function<void()>> signal_handlers;
void on_signal_forwarder(int sig) {
void
on_signal_forwarder(int sig) {
signal_handlers.at(sig)();
}
template <class FN>
void on_signal(int sig, FN &&fn) {
void
on_signal(int sig, FN &&fn) {
signal_handlers.emplace(sig, std::forward<FN>(fn));
std::signal(sig, on_signal_forwarder);
}
namespace gen_creds {
int entry(const char *name, int argc, char *argv[]) {
int
entry(const char *name, int argc, char *argv[]) {
if (argc < 2 || argv[0] == "help"sv || argv[1] == "help"sv) {
print_help(name);
return 0;
@ -148,7 +155,8 @@ std::map<std::string_view, std::function<int(const char *name, int argc, char **
};
#ifdef _WIN32
LRESULT CALLBACK SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
LRESULT CALLBACK
SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_ENDSESSION: {
// Raise a SIGINT to trigger our cleanup logic and terminate ourselves
@ -176,7 +184,8 @@ LRESULT CALLBACK SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
* main(1, const char* args[] = {"sunshine", nullptr});
* ```
*/
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
task_pool_util::TaskPool::task_id_t force_shutdown = nullptr;
#ifdef _WIN32
@ -395,7 +404,8 @@ int main(int argc, char *argv[]) {
* std::string contents = read_file("path/to/file");
* ```
*/
std::string read_file(const char *path) {
std::string
read_file(const char *path) {
if (!std::filesystem::exists(path)) {
BOOST_LOG(debug) << "Missing file: " << path;
return {};
@ -425,7 +435,8 @@ std::string read_file(const char *path) {
* int write_status = write_file("path/to/file", "file contents");
* ```
*/
int write_file(const char *path, const std::string_view &contents) {
int
write_file(const char *path, const std::string_view &contents) {
std::ofstream out(path);
if (!out.is_open()) {
@ -447,7 +458,8 @@ int write_file(const char *path, const std::string_view &contents) {
* std::uint16_t mapped_port = map_port(1);
* ```
*/
std::uint16_t map_port(int port) {
std::uint16_t
map_port(int port) {
// TODO: Ensure port is in the range of 21-65535
// TODO: Ensure port is not already in use by another application
return (std::uint16_t)((int) config::sunshine.port + port);

View file

@ -28,19 +28,32 @@ extern boost::log::sources::severity_logger<int> error;
extern boost::log::sources::severity_logger<int> fatal;
// functions
int main(int argc, char *argv[]);
void log_flush();
void open_url(const std::string &url);
void tray_open_ui_cb(struct tray_menu *item);
void tray_donate_github_cb(struct tray_menu *item);
void tray_donate_mee6_cb(struct tray_menu *item);
void tray_donate_patreon_cb(struct tray_menu *item);
void tray_donate_paypal_cb(struct tray_menu *item);
void tray_quit_cb(struct tray_menu *item);
void print_help(const char *name);
std::string read_file(const char *path);
int write_file(const char *path, const std::string_view &contents);
std::uint16_t map_port(int port);
int
main(int argc, char *argv[]);
void
log_flush();
void
open_url(const std::string &url);
void
tray_open_ui_cb(struct tray_menu *item);
void
tray_donate_github_cb(struct tray_menu *item);
void
tray_donate_mee6_cb(struct tray_menu *item);
void
tray_donate_patreon_cb(struct tray_menu *item);
void
tray_donate_paypal_cb(struct tray_menu *item);
void
tray_quit_cb(struct tray_menu *item);
void
print_help(const char *name);
std::string
read_file(const char *path);
int
write_file(const char *path, const std::string_view &contents);
std::uint16_t
map_port(int port);
// namespaces
namespace mail {

View file

@ -16,7 +16,8 @@ private:
move_type _to_move;
public:
explicit MoveByCopy(move_type &&to_move) : _to_move(std::move(to_move)) {}
explicit MoveByCopy(move_type &&to_move):
_to_move(std::move(to_move)) {}
MoveByCopy(MoveByCopy &&other) = default;
@ -24,9 +25,11 @@ public:
*this = other;
}
MoveByCopy &operator=(MoveByCopy &&other) = default;
MoveByCopy &
operator=(MoveByCopy &&other) = default;
MoveByCopy &operator=(const MoveByCopy &other) {
MoveByCopy &
operator=(const MoveByCopy &other) {
this->_to_move = std::move(const_cast<MoveByCopy &>(other)._to_move);
return *this;
@ -38,13 +41,15 @@ public:
};
template <class T>
MoveByCopy<T> cmove(T &movable) {
MoveByCopy<T>
cmove(T &movable) {
return MoveByCopy<T>(std::move(movable));
}
// Do NOT use this unless you are absolutely certain the object to be moved is no longer used by the caller
template <class T>
MoveByCopy<T> const_cmove(const T &movable) {
MoveByCopy<T>
const_cmove(const T &movable) {
return MoveByCopy<T>(std::move(const_cast<T &>(movable)));
}
} // namespace move_by_copy_util

View file

@ -7,7 +7,8 @@
using namespace std::literals;
namespace net {
// In the format "xxx.xxx.xxx.xxx/x"
std::pair<std::uint32_t, std::uint32_t> ip_block(const std::string_view &ip);
std::pair<std::uint32_t, std::uint32_t>
ip_block(const std::string_view &ip);
std::vector<std::pair<std::uint32_t, std::uint32_t>> pc_ips {
ip_block("127.0.0.1/32"sv)
@ -18,7 +19,8 @@ std::vector<std::tuple<std::uint32_t, std::uint32_t>> lan_ips {
ip_block("10.0.0.0/8"sv)
};
std::uint32_t ip(const std::string_view &ip_str) {
std::uint32_t
ip(const std::string_view &ip_str) {
auto begin = std::begin(ip_str);
auto end = std::end(ip_str);
auto temp_end = std::find(begin, end, '.');
@ -39,7 +41,8 @@ std::uint32_t ip(const std::string_view &ip_str) {
}
// In the format "xxx.xxx.xxx.xxx/x"
std::pair<std::uint32_t, std::uint32_t> ip_block(const std::string_view &ip_str) {
std::pair<std::uint32_t, std::uint32_t>
ip_block(const std::string_view &ip_str) {
auto begin = std::begin(ip_str);
auto end = std::find(begin, std::end(ip_str), '/');
@ -50,7 +53,8 @@ std::pair<std::uint32_t, std::uint32_t> ip_block(const std::string_view &ip_str)
return { addr, addr + ((1 << bits) - 1) };
}
net_e from_enum_string(const std::string_view &view) {
net_e
from_enum_string(const std::string_view &view) {
if (view == "wan") {
return WAN;
}
@ -60,7 +64,8 @@ net_e from_enum_string(const std::string_view &view) {
return PC;
}
net_e from_address(const std::string_view &view) {
net_e
from_address(const std::string_view &view) {
auto addr = ip(view);
for (auto [ip_low, ip_high] : pc_ips) {
@ -78,7 +83,8 @@ net_e from_address(const std::string_view &view) {
return WAN;
}
std::string_view to_enum_string(net_e net) {
std::string_view
to_enum_string(net_e net) {
switch (net) {
case PC:
return "pc"sv;
@ -92,14 +98,16 @@ std::string_view to_enum_string(net_e net) {
return "wan"sv;
}
host_t host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port) {
host_t
host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port) {
enet_address_set_host(&addr, "0.0.0.0");
enet_address_set_port(&addr, port);
return host_t { enet_host_create(AF_INET, &addr, peers, 1, 0, 0) };
}
void free_host(ENetHost *host) {
void
free_host(ENetHost *host) {
std::for_each(host->peers, host->peers + host->peerCount, [](ENetPeer &peer_ref) {
ENetPeer *peer = &peer_ref;

View file

@ -10,7 +10,8 @@
#include "utility.h"
namespace net {
void free_host(ENetHost *host);
void
free_host(ENetHost *host);
using host_t = util::safe_ptr<ENetHost, free_host>;
using peer_t = ENetPeer *;
@ -22,12 +23,16 @@ enum net_e : int {
WAN
};
net_e from_enum_string(const std::string_view &view);
std::string_view to_enum_string(net_e net);
net_e
from_enum_string(const std::string_view &view);
std::string_view
to_enum_string(net_e net);
net_e from_address(const std::string_view &view);
net_e
from_address(const std::string_view &view);
host_t host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port);
host_t
host_create(ENetAddress &addr, std::size_t peers, std::uint16_t port);
} // namespace net
#endif // SUNSHINE_NETWORK_H

View file

@ -38,14 +38,15 @@ namespace pt = boost::property_tree;
class SunshineHttpsServer: public SimpleWeb::Server<SimpleWeb::HTTPS> {
public:
SunshineHttpsServer(const std::string &certification_file, const std::string &private_key_file)
: SimpleWeb::Server<SimpleWeb::HTTPS>::Server(certification_file, private_key_file) {}
SunshineHttpsServer(const std::string &certification_file, const std::string &private_key_file):
SimpleWeb::Server<SimpleWeb::HTTPS>::Server(certification_file, private_key_file) {}
std::function<int(SSL *)> verify;
std::function<void(std::shared_ptr<Response>, std::shared_ptr<Request>)> on_verify_failed;
protected:
void after_bind() override {
void
after_bind() override {
SimpleWeb::Server<SimpleWeb::HTTPS>::after_bind();
if (verify) {
@ -58,7 +59,8 @@ protected:
}
// This is Server<HTTPS>::accept() with SSL validation support added
void accept() override {
void
accept() override {
auto connection = create_connection(*io_service, context);
acceptor->async_accept(connection->socket->lowest_layer(), [this, connection](const SimpleWeb::error_code &ec) {
@ -147,7 +149,8 @@ enum class op_e {
REMOVE
};
std::string get_arg(const args_t &args, const char *name) {
std::string
get_arg(const args_t &args, const char *name) {
auto it = args.find(name);
if (it == std::end(args)) {
throw std::out_of_range(name);
@ -155,7 +158,8 @@ std::string get_arg(const args_t &args, const char *name) {
return it->second;
}
void save_state() {
void
save_state() {
pt::ptree root;
if (fs::exists(config::nvhttp.file_state)) {
@ -197,7 +201,8 @@ void save_state() {
}
}
void load_state() {
void
load_state() {
if (!fs::exists(config::nvhttp.file_state)) {
BOOST_LOG(info) << "File "sv << config::nvhttp.file_state << " doesn't exist"sv;
http::unique_id = uuid_util::uuid_t::generate().string();
@ -236,7 +241,8 @@ void load_state() {
}
}
void update_id_client(const std::string &uniqueID, std::string &&cert, op_e op) {
void
update_id_client(const std::string &uniqueID, std::string &&cert, op_e op) {
switch (op) {
case op_e::ADD: {
auto &client = map_id_client[uniqueID];
@ -253,7 +259,8 @@ void update_id_client(const std::string &uniqueID, std::string &&cert, op_e op)
}
}
rtsp_stream::launch_session_t make_launch_session(bool host_audio, const args_t &args) {
rtsp_stream::launch_session_t
make_launch_session(bool host_audio, const args_t &args) {
rtsp_stream::launch_session_t launch_session;
launch_session.host_audio = host_audio;
@ -267,7 +274,8 @@ rtsp_stream::launch_session_t make_launch_session(bool host_audio, const args_t
return launch_session;
}
void getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin) {
void
getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin) {
if (sess.async_insert_pin.salt.size() < 32) {
tree.put("root.paired", 0);
tree.put("root.<xmlattr>.status_code", 400);
@ -285,7 +293,8 @@ void getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin
tree.put("root.plaincert", util::hex_vec(conf_intern.servercert, true));
tree.put("root.<xmlattr>.status_code", 200);
}
void serverchallengeresp(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
void
serverchallengeresp(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
auto encrypted_response = util::from_hex_vec(get_arg(args, "serverchallengeresp"), true);
std::vector<uint8_t> decrypted;
@ -305,7 +314,8 @@ void serverchallengeresp(pair_session_t &sess, pt::ptree &tree, const args_t &ar
tree.put("root.<xmlattr>.status_code", 200);
}
void clientchallenge(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
void
clientchallenge(pair_session_t &sess, pt::ptree &tree, const args_t &args) {
auto challenge = util::from_hex_vec(get_arg(args, "clientchallenge"), true);
crypto::cipher::ecb_t cipher(*sess.cipher_key, false);
@ -340,7 +350,8 @@ void clientchallenge(pair_session_t &sess, pt::ptree &tree, const args_t &args)
tree.put("root.<xmlattr>.status_code", 200);
}
void clientpairingsecret(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, pair_session_t &sess, pt::ptree &tree, const args_t &args) {
void
clientpairingsecret(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, pair_session_t &sess, pt::ptree &tree, const args_t &args) {
auto &client = sess.client;
auto pairingsecret = util::from_hex_vec(get_arg(args, "clientpairingsecret"), true);
@ -401,7 +412,8 @@ struct tunnel<SimpleWeb::HTTP> {
};
template <class T>
void print_req(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
void
print_req(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
BOOST_LOG(debug) << "TUNNEL :: "sv << tunnel<T>::to_string;
BOOST_LOG(debug) << "METHOD :: "sv << request->method;
@ -421,7 +433,8 @@ void print_req(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> reque
}
template <class T>
void not_found(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
void
not_found(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
print_req<T>(request);
pt::ptree tree;
@ -440,7 +453,8 @@ void not_found(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> resp
}
template <class T>
void pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
void
pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
print_req<T>(request);
pt::ptree tree;
@ -520,7 +534,8 @@ void pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_
* bool pin_status = nvhttp::pin("1234");
* ```
*/
bool pin(std::string pin) {
bool
pin(std::string pin) {
pt::ptree tree;
if (map_id_sess.empty()) {
return false;
@ -551,7 +566,8 @@ bool pin(std::string pin) {
}
template <class T>
void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
void
pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
print_req<T>(request);
response->close_connection_after_response = true;
@ -576,7 +592,8 @@ void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response,
}
template <class T>
void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
void
serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
print_req<T>(request);
int pair_status = 0;
@ -584,7 +601,6 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
auto args = request->parse_query_string();
auto clientID = args.find("uniqueid"s);
if (clientID != std::end(args)) {
if (auto it = map_id_client.find(clientID->second); it != std::end(map_id_client)) {
pair_status = 1;
@ -659,7 +675,8 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
response->close_connection_after_response = true;
}
void applist(resp_https_t response, req_https_t request) {
void
applist(resp_https_t response, req_https_t request) {
print_req<SimpleWeb::HTTPS>(request);
pt::ptree tree;
@ -703,7 +720,8 @@ void applist(resp_https_t response, req_https_t request) {
}
}
void launch(bool &host_audio, resp_https_t response, req_https_t request) {
void
launch(bool &host_audio, resp_https_t response, req_https_t request) {
print_req<SimpleWeb::HTTPS>(request);
pt::ptree tree;
@ -728,7 +746,6 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
args.find("rikeyid"s) == std::end(args) ||
args.find("localAudioPlayMode"s) == std::end(args) ||
args.find("appid"s) == std::end(args)) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 400);
@ -763,7 +780,8 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
tree.put("root.gamesession", 1);
}
void resume(bool &host_audio, resp_https_t response, req_https_t request) {
void
resume(bool &host_audio, resp_https_t response, req_https_t request) {
print_req<SimpleWeb::HTTPS>(request);
pt::ptree tree;
@ -796,7 +814,6 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
if (
args.find("rikey"s) == std::end(args) ||
args.find("rikeyid"s) == std::end(args)) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 400);
@ -810,7 +827,8 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
tree.put("root.resume", 1);
}
void cancel(resp_https_t response, req_https_t request) {
void
cancel(resp_https_t response, req_https_t request) {
print_req<SimpleWeb::HTTPS>(request);
pt::ptree tree;
@ -839,8 +857,8 @@ void cancel(resp_https_t response, req_https_t request) {
}
}
void appasset(resp_https_t response, req_https_t request) {
void
appasset(resp_https_t response, req_https_t request) {
print_req<SimpleWeb::HTTPS>(request);
auto args = request->parse_query_string();
@ -861,7 +879,8 @@ void appasset(resp_https_t response, req_https_t request) {
* nvhttp::start();
* ```
*/
void start() {
void
start() {
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
auto port_http = map_port(PORT_HTTP);
@ -905,7 +924,6 @@ void start() {
auto fg = util::fail_guard([&]() {
char subject_name[256];
X509_NAME_oneline(X509_get_subject_name(x509), subject_name, sizeof(subject_name));
BOOST_LOG(debug) << subject_name << " -- "sv << (verified ? "verified"sv : "denied"sv);
@ -1007,7 +1025,8 @@ void start() {
* nvhttp::erase_all_clients();
* ```
*/
void erase_all_clients() {
void
erase_all_clients() {
map_id_client.clear();
save_state();
}

View file

@ -39,9 +39,12 @@ constexpr auto PORT_HTTP = 0;
constexpr auto PORT_HTTPS = -5;
// functions
void start();
bool pin(std::string pin);
void erase_all_clients();
void
start();
bool
pin(std::string pin);
void
erase_all_clients();
} // namespace nvhttp
#endif // SUNSHINE_NVHTTP_H

View file

@ -69,8 +69,8 @@ constexpr std::uint16_t Y = 0x8000;
struct rumble_t {
KITTY_DEFAULT_CONSTR(rumble_t)
rumble_t(std::uint16_t id, std::uint16_t lowfreq, std::uint16_t highfreq)
: id { id }, lowfreq { lowfreq }, highfreq { highfreq } {}
rumble_t(std::uint16_t id, std::uint16_t lowfreq, std::uint16_t highfreq):
id { id }, lowfreq { lowfreq }, highfreq { highfreq } {}
std::uint16_t id;
std::uint16_t lowfreq;
@ -130,7 +130,8 @@ enum class pix_fmt_e {
unknown
};
inline std::string_view from_pix_fmt(pix_fmt_e pix_fmt) {
inline std::string_view
from_pix_fmt(pix_fmt_e pix_fmt) {
using namespace std::literals;
#define _CONVERT(x) \
case pix_fmt_e::x: \
@ -174,8 +175,10 @@ public:
img_t(img_t &&) = delete;
img_t(const img_t &) = delete;
img_t &operator=(img_t &&) = delete;
img_t &operator=(const img_t &) = delete;
img_t &
operator=(img_t &&) = delete;
img_t &
operator=(const img_t &) = delete;
std::uint8_t *data {};
std::int32_t width {};
@ -204,29 +207,34 @@ struct hwdevice_t {
void *data {};
AVFrame *frame {};
virtual int convert(platf::img_t &img) {
virtual int
convert(platf::img_t &img) {
return -1;
}
/**
* implementations must take ownership of 'frame'
*/
virtual int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
virtual int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
BOOST_LOG(error) << "Illegal call to hwdevice_t::set_frame(). Did you forget to override it?";
return -1;
};
virtual void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {};
virtual void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {};
/**
* Implementations may set parameters during initialization of the hwframes context
*/
virtual void init_hwframes(AVHWFramesContext *frames) {};
virtual void
init_hwframes(AVHWFramesContext *frames) {};
/**
* Implementations may make modifications required before context derivation
*/
virtual int prepare_to_derive_context(int hw_device_type) {
virtual int
prepare_to_derive_context(int hw_device_type) {
return 0;
};
@ -255,7 +263,8 @@ public:
*/
using snapshot_cb_t = std::function<std::shared_ptr<img_t>(std::shared_ptr<img_t> &img, bool frame_captured)>;
display_t() noexcept : offset_x { 0 }, offset_y { 0 } {}
display_t() noexcept:
offset_x { 0 }, offset_y { 0 } {}
/**
* snapshot_cb --> the callback
@ -267,21 +276,27 @@ public:
* capture_e::error on error
* capture_e::reinit when need of reinitialization
*/
virtual capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) = 0;
virtual capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) = 0;
virtual std::shared_ptr<img_t> alloc_img() = 0;
virtual std::shared_ptr<img_t>
alloc_img() = 0;
virtual int dummy_img(img_t *img) = 0;
virtual int
dummy_img(img_t *img) = 0;
virtual std::shared_ptr<hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) {
virtual std::shared_ptr<hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) {
return std::make_shared<hwdevice_t>();
}
virtual bool is_hdr() {
virtual bool
is_hdr() {
return false;
}
virtual bool get_hdr_metadata(SS_HDR_METADATA &metadata) {
virtual bool
get_hdr_metadata(SS_HDR_METADATA &metadata) {
std::memset(&metadata, 0, sizeof(metadata));
return false;
}
@ -297,34 +312,44 @@ public:
class mic_t {
public:
virtual capture_e sample(std::vector<std::int16_t> &frame_buffer) = 0;
virtual capture_e
sample(std::vector<std::int16_t> &frame_buffer) = 0;
virtual ~mic_t() = default;
};
class audio_control_t {
public:
virtual int set_sink(const std::string &sink) = 0;
virtual int
set_sink(const std::string &sink) = 0;
virtual std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) = 0;
virtual std::unique_ptr<mic_t>
microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) = 0;
virtual std::optional<sink_t> sink_info() = 0;
virtual std::optional<sink_t>
sink_info() = 0;
virtual ~audio_control_t() = default;
};
void freeInput(void *);
void
freeInput(void *);
using input_t = util::safe_ptr<void, freeInput>;
std::filesystem::path appdata();
std::filesystem::path
appdata();
std::string get_mac_address(const std::string_view &address);
std::string
get_mac_address(const std::string_view &address);
std::string from_sockaddr(const sockaddr *const);
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const);
std::string
from_sockaddr(const sockaddr *const);
std::pair<std::uint16_t, std::string>
from_sockaddr_ex(const sockaddr *const);
std::unique_ptr<audio_control_t> audio_control();
std::unique_ptr<audio_control_t>
audio_control();
/**
* display_name --> The name of the monitor that SHOULD be displayed
@ -335,12 +360,15 @@ std::unique_ptr<audio_control_t> audio_control();
*
* Returns display_t based on hwdevice_type
*/
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
std::shared_ptr<display_t>
display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
// A list of names of displays accepted as display_name with the mem_type_e
std::vector<std::string> display_names(mem_type_e hwdevice_type);
std::vector<std::string>
display_names(mem_type_e hwdevice_type);
boost::process::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group);
boost::process::child
run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group);
enum class thread_priority_e : int {
low,
@ -348,14 +376,19 @@ enum class thread_priority_e : int {
high,
critical
};
void adjust_thread_priority(thread_priority_e priority);
void
adjust_thread_priority(thread_priority_e priority);
// Allow OS-specific actions to be taken to prepare for streaming
void streaming_will_start();
void streaming_will_stop();
void
streaming_will_start();
void
streaming_will_stop();
bool restart_supported();
bool restart();
bool
restart_supported();
bool
restart();
struct batched_send_info_t {
const char *buffer;
@ -366,37 +399,53 @@ struct batched_send_info_t {
boost::asio::ip::address &target_address;
uint16_t target_port;
};
bool send_batch(batched_send_info_t &send_info);
bool
send_batch(batched_send_info_t &send_info);
enum class qos_data_type_e : int {
audio,
video
};
std::unique_ptr<deinit_t> enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type);
std::unique_ptr<deinit_t>
enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type);
input_t input();
void move_mouse(input_t &input, int deltaX, int deltaY);
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
void button_mouse(input_t &input, int button, bool release);
void scroll(input_t &input, int distance);
void hscroll(input_t &input, int distance);
void keyboard(input_t &input, uint16_t modcode, bool release);
void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state);
void unicode(input_t &input, char *utf8, int size);
input_t
input();
void
move_mouse(input_t &input, int deltaX, int deltaY);
void
abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
void
button_mouse(input_t &input, int button, bool release);
void
scroll(input_t &input, int distance);
void
hscroll(input_t &input, int distance);
void
keyboard(input_t &input, uint16_t modcode, bool release);
void
gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state);
void
unicode(input_t &input, char *utf8, int size);
int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue);
void free_gamepad(input_t &input, int nr);
int
alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue);
void
free_gamepad(input_t &input, int nr);
#define SERVICE_NAME "Sunshine"
#define SERVICE_TYPE "_nvstream._tcp"
namespace publish {
[[nodiscard]] std::unique_ptr<deinit_t> start();
[[nodiscard]] std::unique_ptr<deinit_t>
start();
}
[[nodiscard]] std::unique_ptr<deinit_t> init();
[[nodiscard]] std::unique_ptr<deinit_t>
init();
std::vector<std::string_view> &supported_gamepads();
std::vector<std::string_view> &
supported_gamepads();
} // namespace platf
#endif //SUNSHINE_COMMON_H

View file

@ -30,7 +30,8 @@ constexpr pa_channel_position_t position_mapping[] {
PA_CHANNEL_POSITION_SIDE_RIGHT,
};
std::string to_string(const char *name, const std::uint8_t *mapping, int channels) {
std::string
to_string(const char *name, const std::uint8_t *mapping, int channels) {
std::stringstream ss;
ss << "rate=48000 sink_name="sv << name << " format=s16le channels="sv << channels << " channel_map="sv;
@ -50,7 +51,8 @@ std::string to_string(const char *name, const std::uint8_t *mapping, int channel
struct mic_attr_t: public mic_t {
util::safe_ptr<pa_simple, pa_simple_free> mic;
capture_e sample(std::vector<std::int16_t> &sample_buf) override {
capture_e
sample(std::vector<std::int16_t> &sample_buf) override {
auto sample_size = sample_buf.size();
auto buf = sample_buf.data();
@ -65,7 +67,8 @@ struct mic_attr_t : public mic_t {
}
};
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, std::string source_name) {
std::unique_ptr<mic_t>
microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, std::string source_name) {
auto mic = std::make_unique<mic_attr_t>();
pa_sample_spec ss { PA_SAMPLE_S16LE, sample_rate, (std::uint8_t) channels };
@ -113,7 +116,8 @@ template<class T>
using add_const_t = typename add_const_helper<std::is_pointer_v<T>, T>::type;
template <class T>
void pa_free(T *p) {
void
pa_free(T *p) {
pa_xfree(p);
}
using ctx_t = util::safe_ptr<pa_context, pa_context_unref>;
@ -125,7 +129,8 @@ template<class T>
using cb_simple_t = std::function<void(ctx_t::pointer, add_const_t<T> i)>;
template <class T>
void cb(ctx_t::pointer ctx, add_const_t<T> i, void *userdata) {
void
cb(ctx_t::pointer ctx, add_const_t<T> i, void *userdata) {
auto &f = *(cb_simple_t<T> *) userdata;
// Cannot similarly filter on eol here. Unless reported otherwise assume
@ -137,7 +142,8 @@ template<class T>
using cb_t = std::function<void(ctx_t::pointer, add_const_t<T> i, int eol)>;
template <class T>
void cb(ctx_t::pointer ctx, add_const_t<T> i, int eol, void *userdata) {
void
cb(ctx_t::pointer ctx, add_const_t<T> i, int eol, void *userdata) {
auto &f = *(cb_t<T> *) userdata;
// For some reason, pulseaudio calls this callback after disconnecting
@ -148,19 +154,22 @@ void cb(ctx_t::pointer ctx, add_const_t<T> i, int eol, void *userdata) {
f(ctx, i, eol);
}
void cb_i(ctx_t::pointer ctx, std::uint32_t i, void *userdata) {
void
cb_i(ctx_t::pointer ctx, std::uint32_t i, void *userdata) {
auto alarm = (safe::alarm_raw_t<int> *) userdata;
alarm->ring(i);
}
void ctx_state_cb(ctx_t::pointer ctx, void *userdata) {
void
ctx_state_cb(ctx_t::pointer ctx, void *userdata) {
auto &f = *(std::function<void(ctx_t::pointer)> *) userdata;
f(ctx);
}
void success_cb(ctx_t::pointer ctx, int status, void *userdata) {
void
success_cb(ctx_t::pointer ctx, int status, void *userdata) {
assert(userdata != nullptr);
auto alarm = (safe::alarm_raw_t<int> *) userdata;
@ -189,7 +198,8 @@ public:
std::unique_ptr<std::function<void(ctx_t::pointer)>> events_cb;
std::thread worker;
int init() {
int
init() {
events = std::make_unique<safe::event_t<ctx_event_e>>();
loop.reset(pa_mainloop_new());
ctx.reset(pa_context_new(pa_mainloop_get_api(loop.get()), "sunshine"));
@ -245,7 +255,8 @@ public:
return 0;
}
int load_null(const char *name, const std::uint8_t *channel_mapping, int channels) {
int
load_null(const char *name, const std::uint8_t *channel_mapping, int channels) {
auto alarm = safe::make_alarm<int>();
op_t op {
@ -261,7 +272,8 @@ public:
return *alarm->status();
}
int unload_null(std::uint32_t i) {
int
unload_null(std::uint32_t i) {
if (i == PA_INVALID_INDEX) {
return 0;
}
@ -282,7 +294,8 @@ public:
return 0;
}
std::optional<sink_t> sink_info() override {
std::optional<sink_t>
sink_info() override {
constexpr auto stereo = "sink-sunshine-stereo";
constexpr auto surround51 = "sink-sunshine-surround51";
constexpr auto surround71 = "sink-sunshine-surround71";
@ -382,7 +395,8 @@ public:
return std::make_optional(std::move(sink));
}
std::string get_default_sink_name() {
std::string
get_default_sink_name() {
std::string sink_name;
auto alarm = safe::make_alarm<int>();
@ -404,7 +418,8 @@ public:
return sink_name;
}
std::string get_monitor_name(const std::string &sink_name) {
std::string
get_monitor_name(const std::string &sink_name) {
std::string monitor_name;
auto alarm = safe::make_alarm<int>();
@ -435,7 +450,8 @@ public:
return monitor_name;
}
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
std::unique_ptr<mic_t>
microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
// Sink choice priority:
// 1. Config sink
// 2. Last sink swapped to (Usually virtual in this case)
@ -450,7 +466,8 @@ public:
return ::platf::microphone(mapping, channels, sample_rate, frame_size, get_monitor_name(sink_name));
}
int set_sink(const std::string &sink) override {
int
set_sink(const std::string &sink) override {
auto alarm = safe::make_alarm<int>();
BOOST_LOG(info) << "Setting default sink to: ["sv << sink << "]"sv;
@ -495,7 +512,8 @@ public:
};
} // namespace pa
std::unique_ptr<audio_control_t> audio_control() {
std::unique_ptr<audio_control_t>
audio_control() {
auto audio = std::make_unique<pa::server_t>();
if (audio->init()) {

View file

@ -30,11 +30,13 @@ namespace cuda {
constexpr auto cudaDevAttrMaxThreadsPerBlock = (CUdevice_attribute) 1;
constexpr auto cudaDevAttrMaxThreadsPerMultiProcessor = (CUdevice_attribute) 39;
void pass_error(const std::string_view &sv, const char *name, const char *description) {
void
pass_error(const std::string_view &sv, const char *name, const char *description) {
BOOST_LOG(error) << sv << name << ':' << description;
}
void cff(CudaFunctions *cf) {
void
cff(CudaFunctions *cf) {
cuda_free_functions(&cf);
}
@ -42,7 +44,8 @@ using cdf_t = util::safe_ptr<CudaFunctions, cff>;
static cdf_t cdf;
inline static int check(CUresult result, const std::string_view &sv) {
inline static int
check(CUresult result, const std::string_view &sv) {
if (result != CUDA_SUCCESS) {
const char *name;
const char *description;
@ -57,7 +60,8 @@ inline static int check(CUresult result, const std::string_view &sv) {
return 0;
}
void freeStream(CUstream stream) {
void
freeStream(CUstream stream) {
CU_CHECK_IGNORE(cdf->cuStreamDestroy(stream), "Couldn't destroy cuda stream");
}
@ -66,7 +70,8 @@ public:
tex_t tex;
};
int init() {
int
init() {
auto status = cuda_load_functions(&cdf, nullptr);
if (status) {
BOOST_LOG(error) << "Couldn't load cuda: "sv << status;
@ -81,7 +86,8 @@ int init() {
class cuda_t: public platf::hwdevice_t {
public:
int init(int in_width, int in_height) {
int
init(int in_width, int in_height) {
if (!cdf) {
BOOST_LOG(warning) << "cuda not initialized"sv;
return -1;
@ -95,7 +101,8 @@ public:
return 0;
}
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
this->hwframe.reset(frame);
this->frame = frame;
@ -133,7 +140,8 @@ public:
return 0;
}
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
sws.set_colorspace(colorspace, color_range);
auto tex = tex_t::make(height, width * 4);
@ -161,7 +169,8 @@ public:
sws.convert(frame->data[0], frame->data[1], frame->linesize[0], frame->linesize[1], tex->texture.linear, stream.get(), { frame->width, frame->height, 0, 0 });
}
cudaTextureObject_t tex_obj(const tex_t &tex) const {
cudaTextureObject_t
tex_obj(const tex_t &tex) const {
return linear_interpolation ? tex.texture.linear : tex.texture.point;
}
@ -178,11 +187,13 @@ public:
class cuda_ram_t: public cuda_t {
public:
int convert(platf::img_t &img) override {
int
convert(platf::img_t &img) override {
return sws.load_ram(img, tex.array) || sws.convert(frame->data[0], frame->data[1], frame->linesize[0], frame->linesize[1], tex_obj(tex), stream.get());
}
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
if (cuda_t::set_frame(frame, hw_frames_ctx)) {
return -1;
}
@ -202,12 +213,14 @@ public:
class cuda_vram_t: public cuda_t {
public:
int convert(platf::img_t &img) override {
int
convert(platf::img_t &img) override {
return sws.convert(frame->data[0], frame->data[1], frame->linesize[0], frame->linesize[1], tex_obj(((img_t *) &img)->tex), stream.get());
}
};
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, bool vram) {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, bool vram) {
if (init()) {
return nullptr;
}
@ -232,12 +245,14 @@ namespace nvfbc {
static PNVFBCCREATEINSTANCE createInstance {};
static NVFBC_API_FUNCTION_LIST func { NVFBC_VERSION };
static constexpr inline NVFBC_BOOL nv_bool(bool b) {
static constexpr inline NVFBC_BOOL
nv_bool(bool b) {
return b ? NVFBC_TRUE : NVFBC_FALSE;
}
static void *handle { nullptr };
int init() {
int
init() {
static bool funcs_loaded = false;
if (funcs_loaded) return 0;
@ -304,18 +319,21 @@ class handle_t {
public:
handle_t() = default;
handle_t(handle_t &&other) : handle_flags { other.handle_flags }, handle { other.handle } {
handle_t(handle_t &&other):
handle_flags { other.handle_flags }, handle { other.handle } {
other.handle_flags.reset();
}
handle_t &operator=(handle_t &&other) {
handle_t &
operator=(handle_t &&other) {
std::swap(handle_flags, other.handle_flags);
std::swap(handle, other.handle);
return *this;
}
static std::optional<handle_t> make() {
static std::optional<handle_t>
make() {
NVFBC_CREATE_HANDLE_PARAMS params { NVFBC_CREATE_HANDLE_PARAMS_VER };
handle_t handle;
@ -331,11 +349,13 @@ public:
return std::move(handle);
}
const char *last_error() {
const char *
last_error() {
return func.nvFBCGetLastErrorStr(handle);
}
std::optional<NVFBC_GET_STATUS_PARAMS> status() {
std::optional<NVFBC_GET_STATUS_PARAMS>
status() {
NVFBC_GET_STATUS_PARAMS params { NVFBC_GET_STATUS_PARAMS_VER };
auto status = func.nvFBCGetStatus(handle, &params);
@ -348,7 +368,8 @@ public:
return params;
}
int capture(NVFBC_CREATE_CAPTURE_SESSION_PARAMS &capture_params) {
int
capture(NVFBC_CREATE_CAPTURE_SESSION_PARAMS &capture_params) {
if (func.nvFBCCreateCaptureSession(handle, &capture_params)) {
BOOST_LOG(error) << "Failed to start capture session: "sv << last_error();
return -1;
@ -368,7 +389,8 @@ public:
return 0;
}
int stop() {
int
stop() {
if (!handle_flags[SESSION_CAPTURE]) {
return 0;
}
@ -386,7 +408,8 @@ public:
return 0;
}
int reset() {
int
reset() {
if (!handle_flags[SESSION_HANDLE]) {
return 0;
}
@ -415,7 +438,8 @@ public:
class display_t: public platf::display_t {
public:
int init(const std::string_view &display_name, const ::video::config_t &config) {
int
init(const std::string_view &display_name, const ::video::config_t &config) {
auto handle = handle_t::make();
if (!handle) {
return -1;
@ -479,7 +503,8 @@ public:
return 0;
}
platf::capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
platf::capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
// Force display_t::capture to initialize handle_t::capture
@ -522,7 +547,8 @@ public:
}
// Reinitialize the capture session.
platf::capture_e reinit(bool cursor) {
platf::capture_e
reinit(bool cursor) {
if (handle.stop()) {
return platf::capture_e::error;
}
@ -591,7 +617,8 @@ public:
return platf::capture_e::ok;
}
platf::capture_e snapshot(platf::img_t *img, std::chrono::milliseconds timeout, bool cursor) {
platf::capture_e
snapshot(platf::img_t *img, std::chrono::milliseconds timeout, bool cursor) {
if (cursor != cursor_visible) {
auto status = reinit(cursor);
if (status != platf::capture_e::ok) {
@ -626,11 +653,13 @@ public:
return platf::capture_e::ok;
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(platf::pix_fmt_e pix_fmt) override {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(platf::pix_fmt_e pix_fmt) override {
return ::cuda::make_hwdevice(width, height, true);
}
std::shared_ptr<platf::img_t> alloc_img() override {
std::shared_ptr<platf::img_t>
alloc_img() override {
auto img = std::make_shared<cuda::img_t>();
img->data = nullptr;
@ -649,7 +678,8 @@ public:
return img;
};
int dummy_img(platf::img_t *) override {
int
dummy_img(platf::img_t *) override {
return 0;
}
@ -664,7 +694,8 @@ public:
} // namespace cuda
namespace platf {
std::shared_ptr<display_t> nvfbc_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t>
nvfbc_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
if (hwdevice_type != mem_type_e::cuda) {
BOOST_LOG(error) << "Could not initialize nvfbc display with the given hw device type"sv;
return nullptr;
@ -679,7 +710,8 @@ std::shared_ptr<display_t> nvfbc_display(mem_type_e hwdevice_type, const std::st
return display;
}
std::vector<std::string> nvfbc_display_names() {
std::vector<std::string>
nvfbc_display_names() {
if (cuda::init() || cuda::nvfbc::init()) {
return {};
}

View file

@ -14,10 +14,13 @@ class img_t;
namespace cuda {
namespace nvfbc {
std::vector<std::string> display_names();
std::vector<std::string>
display_names();
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, bool vram);
int init();
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, bool vram);
int
init();
} // namespace cuda
typedef struct cudaArray *cudaArray_t;
@ -34,18 +37,21 @@ namespace cuda {
class freeCudaPtr_t {
public:
void operator()(void *ptr);
void
operator()(void *ptr);
};
class freeCudaStream_t {
public:
void operator()(cudaStream_t ptr);
void
operator()(cudaStream_t ptr);
};
using ptr_t = std::unique_ptr<void, freeCudaPtr_t>;
using stream_t = std::unique_ptr<CUstream_st, freeCudaStream_t>;
stream_t make_stream(int flags = 0);
stream_t
make_stream(int flags = 0);
struct viewport_t {
int width, height;
@ -54,16 +60,19 @@ struct viewport_t {
class tex_t {
public:
static std::optional<tex_t> make(int height, int pitch);
static std::optional<tex_t>
make(int height, int pitch);
tex_t();
tex_t(tex_t &&);
tex_t &operator=(tex_t &&other);
tex_t &
operator=(tex_t &&other);
~tex_t();
int copy(std::uint8_t *src, int height, int pitch);
int
copy(std::uint8_t *src, int height, int pitch);
cudaArray_t array;
@ -84,15 +93,20 @@ public:
*
* pitch -- The size of a single row of pixels in bytes
*/
static std::optional<sws_t> make(int in_width, int in_height, int out_width, int out_height, int pitch);
static std::optional<sws_t>
make(int in_width, int in_height, int out_width, int out_height, int pitch);
// Converts loaded image into a CUDevicePtr
int convert(std::uint8_t *Y, std::uint8_t *UV, std::uint32_t pitchY, std::uint32_t pitchUV, cudaTextureObject_t texture, stream_t::pointer stream);
int convert(std::uint8_t *Y, std::uint8_t *UV, std::uint32_t pitchY, std::uint32_t pitchUV, cudaTextureObject_t texture, stream_t::pointer stream, const viewport_t &viewport);
int
convert(std::uint8_t *Y, std::uint8_t *UV, std::uint32_t pitchY, std::uint32_t pitchUV, cudaTextureObject_t texture, stream_t::pointer stream);
int
convert(std::uint8_t *Y, std::uint8_t *UV, std::uint32_t pitchY, std::uint32_t pitchUV, cudaTextureObject_t texture, stream_t::pointer stream, const viewport_t &viewport);
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
int load_ram(platf::img_t &img, cudaArray_t array);
int
load_ram(platf::img_t &img, cudaArray_t array);
ptr_t color_matrix;

View file

@ -23,7 +23,8 @@ using namespace std::literals;
namespace gl {
GladGLContext ctx;
void drain_errors(const std::string_view &prefix) {
void
drain_errors(const std::string_view &prefix) {
GLenum err;
while ((err = ctx.GetError()) != GL_NO_ERROR) {
BOOST_LOG(error) << "GL: "sv << prefix << ": ["sv << util::hex(err).to_string_view() << ']';
@ -36,7 +37,8 @@ tex_t::~tex_t() {
}
}
tex_t tex_t::make(std::size_t count) {
tex_t
tex_t::make(std::size_t count) {
tex_t textures { count };
ctx.GenTextures(textures.size(), textures.begin());
@ -61,7 +63,8 @@ frame_buf_t::~frame_buf_t() {
}
}
frame_buf_t frame_buf_t::make(std::size_t count) {
frame_buf_t
frame_buf_t::make(std::size_t count) {
frame_buf_t frame_buf { count };
ctx.GenFramebuffers(frame_buf.size(), frame_buf.begin());
@ -69,14 +72,16 @@ frame_buf_t frame_buf_t::make(std::size_t count) {
return frame_buf;
}
void frame_buf_t::copy(int id, int texture, int offset_x, int offset_y, int width, int height) {
void
frame_buf_t::copy(int id, int texture, int offset_x, int offset_y, int width, int height) {
gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, (*this)[id]);
gl::ctx.ReadBuffer(GL_COLOR_ATTACHMENT0 + id);
gl::ctx.BindTexture(GL_TEXTURE_2D, texture);
gl::ctx.CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, offset_x, offset_y, width, height);
}
std::string shader_t::err_str() {
std::string
shader_t::err_str() {
int length;
ctx.GetShaderiv(handle(), GL_INFO_LOG_LENGTH, &length);
@ -90,7 +95,8 @@ std::string shader_t::err_str() {
return string;
}
util::Either<shader_t, std::string> shader_t::compile(const std::string_view &source, GLenum type) {
util::Either<shader_t, std::string>
shader_t::compile(const std::string_view &source, GLenum type) {
shader_t shader;
auto data = source.data();
@ -110,11 +116,13 @@ util::Either<shader_t, std::string> shader_t::compile(const std::string_view &so
return shader;
}
GLuint shader_t::handle() const {
GLuint
shader_t::handle() const {
return _shader.el;
}
buffer_t buffer_t::make(util::buffer_t<GLint> &&offsets, const char *block, const std::string_view &data) {
buffer_t
buffer_t::make(util::buffer_t<GLint> &&offsets, const char *block, const std::string_view &data) {
buffer_t buffer;
buffer._block = block;
buffer._size = data.size();
@ -127,20 +135,24 @@ buffer_t buffer_t::make(util::buffer_t<GLint> &&offsets, const char *block, cons
return buffer;
}
GLuint buffer_t::handle() const {
GLuint
buffer_t::handle() const {
return _buffer.el;
}
const char *buffer_t::block() const {
const char *
buffer_t::block() const {
return _block;
}
void buffer_t::update(const std::string_view &view, std::size_t offset) {
void
buffer_t::update(const std::string_view &view, std::size_t offset) {
ctx.BindBuffer(GL_UNIFORM_BUFFER, handle());
ctx.BufferSubData(GL_UNIFORM_BUFFER, offset, view.size(), (const void *) view.data());
}
void buffer_t::update(std::string_view *members, std::size_t count, std::size_t offset) {
void
buffer_t::update(std::string_view *members, std::size_t count, std::size_t offset) {
util::buffer_t<std::uint8_t> buffer { _size };
for (int x = 0; x < count; ++x) {
@ -152,7 +164,8 @@ void buffer_t::update(std::string_view *members, std::size_t count, std::size_t
update(util::view(buffer.begin(), buffer.end()), offset);
}
std::string program_t::err_str() {
std::string
program_t::err_str() {
int length;
ctx.GetProgramiv(handle(), GL_INFO_LOG_LENGTH, &length);
@ -166,7 +179,8 @@ std::string program_t::err_str() {
return string;
}
util::Either<program_t, std::string> program_t::link(const shader_t &vert, const shader_t &frag) {
util::Either<program_t, std::string>
program_t::link(const shader_t &vert, const shader_t &frag) {
program_t program;
program._program.el = ctx.CreateProgram();
@ -193,14 +207,16 @@ util::Either<program_t, std::string> program_t::link(const shader_t &vert, const
return program;
}
void program_t::bind(const buffer_t &buffer) {
void
program_t::bind(const buffer_t &buffer) {
ctx.UseProgram(handle());
auto i = ctx.GetUniformBlockIndex(handle(), buffer.block());
ctx.BindBufferBase(GL_UNIFORM_BUFFER, i, buffer.handle());
}
std::optional<buffer_t> program_t::uniform(const char *block, std::pair<const char *, std::string_view> *members, std::size_t count) {
std::optional<buffer_t>
program_t::uniform(const char *block, std::pair<const char *, std::string_view> *members, std::size_t count) {
auto i = ctx.GetUniformBlockIndex(handle(), block);
if (i == GL_INVALID_INDEX) {
BOOST_LOG(error) << "Couldn't find index of ["sv << block << ']';
@ -248,7 +264,8 @@ std::optional<buffer_t> program_t::uniform(const char *block, std::pair<const ch
return buffer_t::make(std::move(offsets), block, std::string_view { (char *) buffer.begin(), buffer.size() });
}
GLuint program_t::handle() const {
GLuint
program_t::handle() const {
return _program.el;
}
@ -258,7 +275,8 @@ namespace gbm {
device_destroy_fn device_destroy;
create_device_fn create_device;
int init() {
int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -309,11 +327,13 @@ constexpr auto EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT = 0x3448;
constexpr auto EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT = 0x3449;
constexpr auto EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT = 0x344A;
bool fail() {
bool
fail() {
return eglGetError() != EGL_SUCCESS;
}
display_t make_display(std::variant<gbm::gbm_t::pointer, wl_display *, _XDisplay *> native_display) {
display_t
make_display(std::variant<gbm::gbm_t::pointer, wl_display *, _XDisplay *> native_display) {
constexpr auto EGL_PLATFORM_GBM_MESA = 0x31D7;
constexpr auto EGL_PLATFORM_WAYLAND_KHR = 0x31D8;
constexpr auto EGL_PLATFORM_X11_KHR = 0x31D5;
@ -378,7 +398,8 @@ display_t make_display(std::variant<gbm::gbm_t::pointer, wl_display *, _XDisplay
return display;
}
std::optional<ctx_t> make_ctx(display_t::pointer display) {
std::optional<ctx_t>
make_ctx(display_t::pointer display) {
constexpr int conf_attr[] {
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE
};
@ -434,7 +455,8 @@ struct plane_attr_t {
EGLAttrib hi;
};
inline plane_attr_t get_plane(std::uint32_t plane_indice) {
inline plane_attr_t
get_plane(std::uint32_t plane_indice) {
switch (plane_indice) {
case 0:
return {
@ -474,7 +496,8 @@ inline plane_attr_t get_plane(std::uint32_t plane_indice) {
return {};
}
std::optional<rgb_t> import_source(display_t::pointer egl_display, const surface_descriptor_t &xrgb) {
std::optional<rgb_t>
import_source(display_t::pointer egl_display, const surface_descriptor_t &xrgb) {
EGLAttrib attribs[47];
int atti = 0;
attribs[atti++] = EGL_WIDTH;
@ -531,7 +554,8 @@ std::optional<rgb_t> import_source(display_t::pointer egl_display, const surface
return rgb;
}
std::optional<nv12_t> import_target(display_t::pointer egl_display, std::array<file_t, nv12_img_t::num_fds> &&fds, const surface_descriptor_t &r8, const surface_descriptor_t &gr88) {
std::optional<nv12_t>
import_target(display_t::pointer egl_display, std::array<file_t, nv12_img_t::num_fds> &&fds, const surface_descriptor_t &r8, const surface_descriptor_t &gr88) {
EGLAttrib img_attr_planes[2][13] {
{ EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_R8,
EGL_WIDTH, r8.width,
@ -578,7 +602,8 @@ std::optional<nv12_t> import_target(display_t::pointer egl_display, std::array<f
return nv12;
}
void sws_t::set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {
void
sws_t::set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {
video::color_t *color_p;
switch (colorspace) {
case 5: // SWS_CS_SMPTE170M
@ -614,7 +639,8 @@ void sws_t::set_colorspace(std::uint32_t colorspace, std::uint32_t color_range)
program[1].bind(color_matrix);
}
std::optional<sws_t> sws_t::make(int in_width, int in_height, int out_width, int out_heigth, gl::tex_t &&tex) {
std::optional<sws_t>
sws_t::make(int in_width, int in_height, int out_width, int out_heigth, gl::tex_t &&tex) {
sws_t sws;
sws.serial = std::numeric_limits<std::uint64_t>::max();
@ -742,7 +768,8 @@ std::optional<sws_t> sws_t::make(int in_width, int in_height, int out_width, int
return std::move(sws);
}
int sws_t::blank(gl::frame_buf_t &fb, int offsetX, int offsetY, int width, int height) {
int
sws_t::blank(gl::frame_buf_t &fb, int offsetX, int offsetY, int width, int height) {
auto f = [&]() {
std::swap(offsetX, this->offsetX);
std::swap(offsetY, this->offsetY);
@ -756,7 +783,8 @@ int sws_t::blank(gl::frame_buf_t &fb, int offsetX, int offsetY, int width, int h
return convert(fb);
}
std::optional<sws_t> sws_t::make(int in_width, int in_height, int out_width, int out_heigth) {
std::optional<sws_t>
sws_t::make(int in_width, int in_height, int out_width, int out_heigth) {
auto tex = gl::tex_t::make(2);
gl::ctx.BindTexture(GL_TEXTURE_2D, tex[0]);
gl::ctx.TexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, in_width, in_height);
@ -764,14 +792,16 @@ std::optional<sws_t> sws_t::make(int in_width, int in_height, int out_width, int
return make(in_width, in_height, out_width, out_heigth, std::move(tex));
}
void sws_t::load_ram(platf::img_t &img) {
void
sws_t::load_ram(platf::img_t &img) {
loaded_texture = tex[0];
gl::ctx.BindTexture(GL_TEXTURE_2D, loaded_texture);
gl::ctx.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.width, img.height, GL_BGRA, GL_UNSIGNED_BYTE, img.data);
}
void sws_t::load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture) {
void
sws_t::load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture) {
// When only a sub-part of the image must be encoded...
const bool copy = offset_x || offset_y || img.sd.width != in_width || img.sd.height != in_height;
if (copy) {
@ -831,7 +861,8 @@ void sws_t::load_vram(img_descriptor_t &img, int offset_x, int offset_y, int tex
}
}
int sws_t::convert(gl::frame_buf_t &fb) {
int
sws_t::convert(gl::frame_buf_t &fb) {
gl::ctx.BindTexture(GL_TEXTURE_2D, loaded_texture);
GLenum attachments[] {
@ -864,6 +895,7 @@ int sws_t::convert(gl::frame_buf_t &fb) {
}
} // namespace egl
void free_frame(AVFrame *frame) {
void
free_frame(AVFrame *frame) {
av_frame_free(&frame);
}

View file

@ -17,30 +17,35 @@
#define gl_drain_errors_helper(x) gl::drain_errors(x)
#define gl_drain_errors gl_drain_errors_helper(__FILE__ ":" SUNSHINE_STRINGIFY(__LINE__))
extern "C" int close(int __fd);
extern "C" int
close(int __fd);
// X11 Display
extern "C" struct _XDisplay;
struct AVFrame;
void free_frame(AVFrame *frame);
void
free_frame(AVFrame *frame);
using frame_t = util::safe_ptr<AVFrame, free_frame>;
namespace gl {
extern GladGLContext ctx;
void drain_errors(const std::string_view &prefix);
void
drain_errors(const std::string_view &prefix);
class tex_t: public util::buffer_t<GLuint> {
using util::buffer_t<GLuint>::buffer_t;
public:
tex_t(tex_t &&) = default;
tex_t &operator=(tex_t &&) = default;
tex_t &
operator=(tex_t &&) = default;
~tex_t();
static tex_t make(std::size_t count);
static tex_t
make(std::size_t count);
};
class frame_buf_t: public util::buffer_t<GLuint> {
@ -48,13 +53,16 @@ class frame_buf_t : public util::buffer_t<GLuint> {
public:
frame_buf_t(frame_buf_t &&) = default;
frame_buf_t &operator=(frame_buf_t &&) = default;
frame_buf_t &
operator=(frame_buf_t &&) = default;
~frame_buf_t();
static frame_buf_t make(std::size_t count);
static frame_buf_t
make(std::size_t count);
inline void bind(std::nullptr_t, std::nullptr_t) {
inline void
bind(std::nullptr_t, std::nullptr_t) {
int x = 0;
for (auto fb : (*this)) {
ctx.BindFramebuffer(GL_FRAMEBUFFER, fb);
@ -66,7 +74,8 @@ public:
}
template <class It>
void bind(It it_begin, It it_end) {
void
bind(It it_begin, It it_end) {
using namespace std::literals;
if (std::distance(it_begin, it_end) > size()) {
BOOST_LOG(warning) << "To many elements to bind"sv;
@ -87,7 +96,8 @@ public:
/**
* Copies a part of the framebuffer to texture
*/
void copy(int id, int texture, int offset_x, int offset_y, int width, int height);
void
copy(int id, int texture, int offset_x, int offset_y, int width, int height);
};
class shader_t {
@ -98,11 +108,14 @@ class shader_t {
});
public:
std::string err_str();
std::string
err_str();
static util::Either<shader_t, std::string> compile(const std::string_view &source, GLenum type);
static util::Either<shader_t, std::string>
compile(const std::string_view &source, GLenum type);
GLuint handle() const;
GLuint
handle() const;
private:
shader_internal_t _shader;
@ -116,14 +129,19 @@ class buffer_t {
});
public:
static buffer_t make(util::buffer_t<GLint> &&offsets, const char *block, const std::string_view &data);
static buffer_t
make(util::buffer_t<GLint> &&offsets, const char *block, const std::string_view &data);
GLuint handle() const;
GLuint
handle() const;
const char *block() const;
const char *
block() const;
void update(const std::string_view &view, std::size_t offset = 0);
void update(std::string_view *members, std::size_t count, std::size_t offset = 0);
void
update(const std::string_view &view, std::size_t offset = 0);
void
update(std::string_view *members, std::size_t count, std::size_t offset = 0);
private:
const char *_block;
@ -143,15 +161,20 @@ class program_t {
});
public:
std::string err_str();
std::string
err_str();
static util::Either<program_t, std::string> link(const shader_t &vert, const shader_t &frag);
static util::Either<program_t, std::string>
link(const shader_t &vert, const shader_t &frag);
void bind(const buffer_t &buffer);
void
bind(const buffer_t &buffer);
std::optional<buffer_t> uniform(const char *block, std::pair<const char *, std::string_view> *members, std::size_t count);
std::optional<buffer_t>
uniform(const char *block, std::pair<const char *, std::string_view> *members, std::size_t count);
GLuint handle() const;
GLuint
handle() const;
private:
program_internal_t _program;
@ -168,7 +191,8 @@ extern create_device_fn create_device;
using gbm_t = util::dyn_safe_ptr<device, &device_destroy>;
int init();
int
init();
} // namespace gbm
@ -230,14 +254,18 @@ struct surface_descriptor_t {
std::uint32_t offsets[4];
};
display_t make_display(std::variant<gbm::gbm_t::pointer, wl_display *, _XDisplay *> native_display);
std::optional<ctx_t> make_ctx(display_t::pointer display);
display_t
make_display(std::variant<gbm::gbm_t::pointer, wl_display *, _XDisplay *> native_display);
std::optional<ctx_t>
make_ctx(display_t::pointer display);
std::optional<rgb_t> import_source(
std::optional<rgb_t>
import_source(
display_t::pointer egl_display,
const surface_descriptor_t &xrgb);
std::optional<nv12_t> import_target(
std::optional<nv12_t>
import_target(
display_t::pointer egl_display,
std::array<file_t, nv12_img_t::num_fds> &&fds,
const surface_descriptor_t &r8, const surface_descriptor_t &gr88);
@ -258,7 +286,8 @@ public:
reset();
}
void reset() {
void
reset() {
for (auto x = 0; x < 4; ++x) {
if (sd.fds[x] >= 0) {
close(sd.fds[x]);
@ -276,19 +305,26 @@ public:
class sws_t {
public:
static std::optional<sws_t> make(int in_width, int in_height, int out_width, int out_heigth, gl::tex_t &&tex);
static std::optional<sws_t> make(int in_width, int in_height, int out_width, int out_heigth);
static std::optional<sws_t>
make(int in_width, int in_height, int out_width, int out_heigth, gl::tex_t &&tex);
static std::optional<sws_t>
make(int in_width, int in_height, int out_width, int out_heigth);
// Convert the loaded image into the first two framebuffers
int convert(gl::frame_buf_t &fb);
int
convert(gl::frame_buf_t &fb);
// Make an area of the image black
int blank(gl::frame_buf_t &fb, int offsetX, int offsetY, int width, int height);
int
blank(gl::frame_buf_t &fb, int offsetX, int offsetY, int width, int height);
void load_ram(platf::img_t &img);
void load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture);
void
load_ram(platf::img_t &img);
void
load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture);
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
// The first texture is the monitor image.
// The second texture is the cursor image
@ -313,7 +349,8 @@ public:
std::uint64_t serial;
};
bool fail();
bool
fail();
} // namespace egl
#endif

View file

@ -54,7 +54,8 @@ _FN(FakeRelativeMotionEvent, int, (Display * dpy, int deltaX, int deltaY, unsign
_FN(FakeButtonEvent, int, (Display * dpy, unsigned int button, Bool is_press, unsigned long delay));
_FN(FakeKeyEvent, int, (Display * dpy, unsigned int keycode, Bool is_press, unsigned long delay));
static int init() {
static int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -83,7 +84,8 @@ static int init() {
}
} // namespace tst
static int init() {
static int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -144,7 +146,8 @@ constexpr auto UNKNOWN = 0;
* @brief Initializes the keycode constants for translating
* moonlight keycodes to linux/X11 keycodes
*/
static constexpr std::array<keycode_t, 0xE3> init_keycodes() {
static constexpr std::array<keycode_t, 0xE3>
init_keycodes() {
std::array<keycode_t, 0xE3> keycodes {};
#ifdef SUNSHINE_BUILD_X11
@ -301,28 +304,32 @@ constexpr touch_port_t target_touch_port {
19200, 12000
};
static std::pair<std::uint32_t, std::uint32_t> operator*(const std::pair<std::uint32_t, std::uint32_t> &l, int r) {
static std::pair<std::uint32_t, std::uint32_t>
operator*(const std::pair<std::uint32_t, std::uint32_t> &l, int r) {
return {
l.first * r,
l.second * r,
};
}
static std::pair<std::uint32_t, std::uint32_t> operator/(const std::pair<std::uint32_t, std::uint32_t> &l, int r) {
static std::pair<std::uint32_t, std::uint32_t>
operator/(const std::pair<std::uint32_t, std::uint32_t> &l, int r) {
return {
l.first / r,
l.second / r,
};
}
static std::pair<std::uint32_t, std::uint32_t> &operator+=(std::pair<std::uint32_t, std::uint32_t> &l, const std::pair<std::uint32_t, std::uint32_t> &r) {
static std::pair<std::uint32_t, std::uint32_t> &
operator+=(std::pair<std::uint32_t, std::uint32_t> &l, const std::pair<std::uint32_t, std::uint32_t> &r) {
l.first += r.first;
l.second += r.second;
return l;
}
static inline void print(const ff_envelope &envelope) {
static inline void
print(const ff_envelope &envelope) {
BOOST_LOG(debug)
<< "Envelope:"sv << std::endl
<< " attack_length: " << envelope.attack_length << std::endl
@ -331,21 +338,24 @@ static inline void print(const ff_envelope &envelope) {
<< " fade_level: " << envelope.fade_level;
}
static inline void print(const ff_replay &replay) {
static inline void
print(const ff_replay &replay) {
BOOST_LOG(debug)
<< "Replay:"sv << std::endl
<< " length: "sv << replay.length << std::endl
<< " delay: "sv << replay.delay;
}
static inline void print(const ff_trigger &trigger) {
static inline void
print(const ff_trigger &trigger) {
BOOST_LOG(debug)
<< "Trigger:"sv << std::endl
<< " button: "sv << trigger.button << std::endl
<< " interval: "sv << trigger.interval;
}
static inline void print(const ff_effect &effect) {
static inline void
print(const ff_effect &effect) {
BOOST_LOG(debug)
<< std::endl
<< std::endl
@ -392,7 +402,6 @@ static inline void print(const ff_effect &effect) {
<< " weak_magnitude: " << effect.u.rumble.weak_magnitude;
break;
case FF_SPRING:
BOOST_LOG(debug)
<< "FF_SPRING:" << std::endl
@ -439,21 +448,20 @@ class effect_t {
public:
KITTY_DEFAULT_CONSTR_MOVE(effect_t)
effect_t(int gamepadnr, uinput_t::pointer dev, rumble_queue_t &&q)
: gamepadnr { gamepadnr }, dev { dev }, rumble_queue { std::move(q) }, gain { 0xFFFF }, id_to_data {} {}
effect_t(int gamepadnr, uinput_t::pointer dev, rumble_queue_t &&q):
gamepadnr { gamepadnr }, dev { dev }, rumble_queue { std::move(q) }, gain { 0xFFFF }, id_to_data {} {}
class data_t {
public:
KITTY_DEFAULT_CONSTR(data_t)
data_t(const ff_effect &effect)
: delay { effect.replay.delay },
data_t(const ff_effect &effect):
delay { effect.replay.delay },
length { effect.replay.length },
end_point { std::chrono::steady_clock::time_point::min() },
envelope {},
start {},
end {} {
switch (effect.type) {
case FF_CONSTANT:
start.weak = effect.u.constant.level;
@ -493,13 +501,15 @@ public:
}
}
std::uint32_t magnitude(std::chrono::milliseconds time_left, std::uint32_t start, std::uint32_t end) {
std::uint32_t
magnitude(std::chrono::milliseconds time_left, std::uint32_t start, std::uint32_t end) {
auto rel = end - start;
return start + (rel * time_left.count() / length.count());
}
std::pair<std::uint32_t, std::uint32_t> rumble(std::chrono::steady_clock::time_point tp) {
std::pair<std::uint32_t, std::uint32_t>
rumble(std::chrono::steady_clock::time_point tp) {
if (end_point < tp) {
return {};
}
@ -534,11 +544,13 @@ public:
};
}
void activate() {
void
activate() {
end_point = std::chrono::steady_clock::now() + delay + length;
}
void deactivate() {
void
deactivate() {
end_point = std::chrono::steady_clock::time_point::min();
}
@ -557,7 +569,8 @@ public:
} end;
};
std::pair<std::uint32_t, std::uint32_t> rumble(std::chrono::steady_clock::time_point tp) {
std::pair<std::uint32_t, std::uint32_t>
rumble(std::chrono::steady_clock::time_point tp) {
std::pair<std::uint32_t, std::uint32_t> weak_strong {};
for (auto &[_, data] : id_to_data) {
weak_strong += data.rumble(tp);
@ -570,7 +583,8 @@ public:
return old_rumble;
}
void upload(const ff_effect &effect) {
void
upload(const ff_effect &effect) {
print(effect);
auto it = id_to_data.find(effect.id);
@ -586,7 +600,8 @@ public:
it->second = data;
}
void activate(int id) {
void
activate(int id) {
auto it = id_to_data.find(id);
if (it != std::end(id_to_data)) {
@ -594,7 +609,8 @@ public:
}
}
void deactivate(int id) {
void
deactivate(int id) {
auto it = id_to_data.find(id);
if (it != std::end(id_to_data)) {
@ -602,7 +618,8 @@ public:
}
}
void erase(int id) {
void
erase(int id) {
id_to_data.erase(id);
BOOST_LOG(debug) << "Removed rumble effect id ["sv << id << ']';
}
@ -629,14 +646,17 @@ struct rumble_ctx_t {
safe::queue_t<mail_evdev_t> rumble_queue_queue;
};
void broadcastRumble(safe::queue_t<mail_evdev_t> &ctx);
int startRumble(rumble_ctx_t &ctx) {
void
broadcastRumble(safe::queue_t<mail_evdev_t> &ctx);
int
startRumble(rumble_ctx_t &ctx) {
ctx.rumble_thread = std::thread { broadcastRumble, std::ref(ctx.rumble_queue_queue) };
return 0;
}
void stopRumble(rumble_ctx_t &ctx) {
void
stopRumble(rumble_ctx_t &ctx) {
ctx.rumble_queue_queue.stop();
BOOST_LOG(debug) << "Waiting for Gamepad notifications to stop..."sv;
@ -648,7 +668,8 @@ static auto notifications = safe::make_shared<rumble_ctx_t>(startRumble, stopRum
struct input_raw_t {
public:
void clear_touchscreen() {
void
clear_touchscreen() {
std::filesystem::path touch_path { appdata() / "sunshine_touchscreen"sv };
if (std::filesystem::is_symlink(touch_path)) {
@ -658,7 +679,8 @@ public:
touch_input.reset();
}
void clear_keyboard() {
void
clear_keyboard() {
std::filesystem::path key_path { appdata() / "sunshine_keyboard"sv };
if (std::filesystem::is_symlink(key_path)) {
@ -668,7 +690,8 @@ public:
keyboard_input.reset();
}
void clear_mouse() {
void
clear_mouse() {
std::filesystem::path mouse_path { appdata() / "sunshine_mouse"sv };
if (std::filesystem::is_symlink(mouse_path)) {
@ -678,7 +701,8 @@ public:
mouse_input.reset();
}
void clear_gamepad(int nr) {
void
clear_gamepad(int nr) {
auto &[dev, _] = gamepads[nr];
if (!dev) {
@ -700,7 +724,8 @@ public:
gamepads[nr] = std::make_pair(uinput_t {}, gamepad_state_t {});
}
int create_mouse() {
int
create_mouse() {
int err = libevdev_uinput_create_from_device(mouse_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &mouse_input);
if (err) {
@ -713,7 +738,8 @@ public:
return 0;
}
int create_touchscreen() {
int
create_touchscreen() {
int err = libevdev_uinput_create_from_device(touch_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &touch_input);
if (err) {
@ -726,7 +752,8 @@ public:
return 0;
}
int create_keyboard() {
int
create_keyboard() {
int err = libevdev_uinput_create_from_device(keyboard_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &keyboard_input);
if (err) {
@ -739,7 +766,8 @@ public:
return 0;
}
int alloc_gamepad(int nr, rumble_queue_t &&rumble_queue) {
int
alloc_gamepad(int nr, rumble_queue_t &&rumble_queue) {
TUPLE_2D_REF(input, gamepad_state, gamepads[nr]);
int err = libevdev_uinput_create_from_device(gamepad_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &input);
@ -775,7 +803,8 @@ public:
return 0;
}
void clear() {
void
clear() {
clear_touchscreen();
clear_keyboard();
clear_mouse();
@ -812,7 +841,8 @@ public:
#endif
};
inline void rumbleIterate(std::vector<effect_t> &effects, std::vector<pollfd_t> &polls, std::chrono::milliseconds to) {
inline void
rumbleIterate(std::vector<effect_t> &effects, std::vector<pollfd_t> &polls, std::chrono::milliseconds to) {
std::vector<pollfd> polls_recv;
polls_recv.reserve(polls.size());
for (auto &poll : polls) {
@ -947,7 +977,8 @@ inline void rumbleIterate(std::vector<effect_t> &effects, std::vector<pollfd_t>
}
}
void broadcastRumble(safe::queue_t<mail_evdev_t> &rumble_queue_queue) {
void
broadcastRumble(safe::queue_t<mail_evdev_t> &rumble_queue_queue) {
std::vector<effect_t> effects;
std::vector<pollfd_t> polls;
@ -971,7 +1002,6 @@ void broadcastRumble(safe::queue_t<mail_evdev_t> &rumble_queue_queue) {
});
if (effect_it != std::end(effects)) {
auto poll_it = std::begin(polls) + (effect_it - std::begin(effects));
polls.erase(poll_it);
@ -1027,7 +1057,8 @@ void broadcastRumble(safe::queue_t<mail_evdev_t> &rumble_queue_queue) {
* x_abs_mouse(input, 0, 0);
* ```
*/
static void x_abs_mouse(input_t &input, float x, float y) {
static void
x_abs_mouse(input_t &input, float x, float y) {
#ifdef SUNSHINE_BUILD_X11
Display *xdisplay = ((input_raw_t *) input.get())->display;
if (!xdisplay) {
@ -1050,7 +1081,8 @@ static void x_abs_mouse(input_t &input, float x, float y) {
* abs_mouse(input, touch_port, 0, 0);
* ```
*/
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
void
abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
auto touchscreen = ((input_raw_t *) input.get())->touch_input.get();
if (!touchscreen) {
x_abs_mouse(input, x, y);
@ -1079,7 +1111,8 @@ void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y)
* x_move_mouse(input, 10, 10); // Move mouse 10 pixels down and right
* ```
*/
static void x_move_mouse(input_t &input, int deltaX, int deltaY) {
static void
x_move_mouse(input_t &input, int deltaX, int deltaY) {
#ifdef SUNSHINE_BUILD_X11
Display *xdisplay = ((input_raw_t *) input.get())->display;
if (!xdisplay) {
@ -1101,7 +1134,8 @@ static void x_move_mouse(input_t &input, int deltaX, int deltaY) {
* move_mouse(input, 10, 10); // Move mouse 10 pixels down and right
* ```
*/
void move_mouse(input_t &input, int deltaX, int deltaY) {
void
move_mouse(input_t &input, int deltaX, int deltaY) {
auto mouse = ((input_raw_t *) input.get())->mouse_input.get();
if (!mouse) {
x_move_mouse(input, deltaX, deltaY);
@ -1130,7 +1164,8 @@ void move_mouse(input_t &input, int deltaX, int deltaY) {
* x_button_mouse(input, 1, false); // Press left mouse button
* ```
*/
static void x_button_mouse(input_t &input, int button, bool release) {
static void
x_button_mouse(input_t &input, int button, bool release) {
#ifdef SUNSHINE_BUILD_X11
unsigned int x_button = 0;
switch (button) {
@ -1172,7 +1207,8 @@ static void x_button_mouse(input_t &input, int button, bool release) {
* button_mouse(input, 1, false); // Press left mouse button
* ```
*/
void button_mouse(input_t &input, int button, bool release) {
void
button_mouse(input_t &input, int button, bool release) {
auto mouse = ((input_raw_t *) input.get())->mouse_input.get();
if (!mouse) {
x_button_mouse(input, button, release);
@ -1220,7 +1256,8 @@ void button_mouse(input_t &input, int button, bool release) {
* x_scroll(input, 10, 4, 5);
* ```
*/
static void x_scroll(input_t &input, int distance, int button_pos, int button_neg) {
static void
x_scroll(input_t &input, int distance, int button_pos, int button_neg) {
#ifdef SUNSHINE_BUILD_X11
Display *xdisplay = ((input_raw_t *) input.get())->display;
if (!xdisplay) {
@ -1246,7 +1283,8 @@ static void x_scroll(input_t &input, int distance, int button_pos, int button_ne
* scroll(input, 1200);
* ```
*/
void scroll(input_t &input, int high_res_distance) {
void
scroll(input_t &input, int high_res_distance) {
int distance = high_res_distance / 120;
auto mouse = ((input_raw_t *) input.get())->mouse_input.get();
@ -1270,7 +1308,8 @@ void scroll(input_t &input, int high_res_distance) {
* hscroll(input, 1200);
* ```
*/
void hscroll(input_t &input, int high_res_distance) {
void
hscroll(input_t &input, int high_res_distance) {
int distance = high_res_distance / 120;
auto mouse = ((input_raw_t *) input.get())->mouse_input.get();
@ -1284,7 +1323,8 @@ void hscroll(input_t &input, int high_res_distance) {
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
}
static keycode_t keysym(std::uint16_t modcode) {
static keycode_t
keysym(std::uint16_t modcode) {
if (modcode <= keycodes.size()) {
return keycodes[modcode];
}
@ -1303,7 +1343,8 @@ static keycode_t keysym(std::uint16_t modcode) {
* x_keyboard(input, 0x5A, false); // Press Z
* ```
*/
static void x_keyboard(input_t &input, uint16_t modcode, bool release) {
static void
x_keyboard(input_t &input, uint16_t modcode, bool release) {
#ifdef SUNSHINE_BUILD_X11
auto keycode = keysym(modcode);
if (keycode.keysym == UNKNOWN) {
@ -1336,7 +1377,8 @@ static void x_keyboard(input_t &input, uint16_t modcode, bool release) {
* keyboard(input, 0x5A, false); // Press Z
* ```
*/
void keyboard(input_t &input, uint16_t modcode, bool release) {
void
keyboard(input_t &input, uint16_t modcode, bool release) {
auto keyboard = ((input_raw_t *) input.get())->keyboard_input.get();
if (!keyboard) {
x_keyboard(input, modcode, release);
@ -1356,7 +1398,8 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
libevdev_uinput_write_event(keyboard, EV_SYN, SYN_REPORT, 0);
}
void keyboard_ev(libevdev_uinput *keyboard, int linux_code, int event_code = 1) {
void
keyboard_ev(libevdev_uinput *keyboard, int linux_code, int event_code = 1) {
libevdev_uinput_write_event(keyboard, EV_KEY, linux_code, event_code);
libevdev_uinput_write_event(keyboard, EV_SYN, SYN_REPORT, 0);
}
@ -1368,7 +1411,8 @@ void keyboard_ev(libevdev_uinput *keyboard, int linux_code, int event_code = 1)
*
* adapted from: https://stackoverflow.com/a/7639754
*/
std::string to_hex(const std::basic_string<char32_t> &str) {
std::string
to_hex(const std::basic_string<char32_t> &str) {
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (const auto &ch : str) {
@ -1391,7 +1435,8 @@ std::string to_hex(const std::basic_string<char32_t> &str) {
* - then type: CTRL+SHIFT+U+1F471
* see the conversion at: https://www.compart.com/en/unicode/U+1F471
*/
void unicode(input_t &input, char *utf8, int size) {
void
unicode(input_t &input, char *utf8, int size) {
auto kb = ((input_raw_t *) input.get())->keyboard_input.get();
if (!kb) {
return;
@ -1429,18 +1474,20 @@ void unicode(input_t &input, char *utf8, int size) {
keyboard_ev(kb, KEY_LEFTCTRL, 0);
}
int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
int
alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
return ((input_raw_t *) input.get())->alloc_gamepad(nr, std::move(rumble_queue));
}
void free_gamepad(input_t &input, int nr) {
void
free_gamepad(input_t &input, int nr) {
((input_raw_t *) input.get())->clear_gamepad(nr);
}
void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
void
gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
TUPLE_2D_REF(uinput, gamepad_state_old, ((input_raw_t *) input.get())->gamepads[nr]);
auto bf = gamepad_state.buttonFlags ^ gamepad_state_old.buttonFlags;
auto bf_new = gamepad_state.buttonFlags;
@ -1507,7 +1554,8 @@ void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
* auto my_keyboard = keyboard();
* ```
*/
evdev_t keyboard() {
evdev_t
keyboard() {
evdev_t dev { libevdev_new() };
libevdev_set_uniq(dev.get(), "Sunshine Keyboard");
@ -1535,7 +1583,8 @@ evdev_t keyboard() {
* auto my_mouse = mouse();
* ```
*/
evdev_t mouse() {
evdev_t
mouse() {
evdev_t dev { libevdev_new() };
libevdev_set_uniq(dev.get(), "Sunshine Mouse");
@ -1585,7 +1634,8 @@ evdev_t mouse() {
* auto my_touchscreen = touchscreen();
* ```
*/
evdev_t touchscreen() {
evdev_t
touchscreen() {
evdev_t dev { libevdev_new() };
libevdev_set_uniq(dev.get(), "Sunshine Touch");
@ -1597,7 +1647,6 @@ evdev_t touchscreen() {
libevdev_enable_property(dev.get(), INPUT_PROP_DIRECT);
libevdev_enable_event_type(dev.get(), EV_KEY);
libevdev_enable_event_code(dev.get(), EV_KEY, BTN_TOUCH, nullptr);
libevdev_enable_event_code(dev.get(), EV_KEY, BTN_TOOL_PEN, nullptr); // Needed to be enabled for BTN_TOOL_FINGER to work.
@ -1635,7 +1684,8 @@ evdev_t touchscreen() {
* auto my_x360 = x360();
* ```
*/
evdev_t x360() {
evdev_t
x360() {
evdev_t dev { libevdev_new() };
input_absinfo stick {
@ -1711,7 +1761,8 @@ evdev_t x360() {
* auto my_input = input();
* ```
*/
input_t input() {
input_t
input() {
input_t result { new input_raw_t() };
auto &gp = *(input_raw_t *) result.get();
@ -1749,12 +1800,14 @@ input_t input() {
return result;
}
void freeInput(void *p) {
void
freeInput(void *p) {
auto *input = (input_raw_t *) p;
delete input;
}
std::vector<std::string_view> &supported_gamepads() {
std::vector<std::string_view> &
supported_gamepads() {
static std::vector<std::string_view> gamepads { "x360"sv };
return gamepads;

View file

@ -51,8 +51,8 @@ public:
class wrapper_fb {
public:
wrapper_fb(drmModeFB *fb)
: fb { fb }, fb_id { fb->fb_id }, width { fb->width }, height { fb->height } {
wrapper_fb(drmModeFB *fb):
fb { fb }, fb_id { fb->fb_id }, width { fb->width }, height { fb->height } {
pixel_format = DRM_FORMAT_XRGB8888;
modifier = DRM_FORMAT_MOD_INVALID;
std::fill_n(handles, 4, 0);
@ -62,8 +62,8 @@ public:
pitches[0] = fb->pitch;
}
wrapper_fb(drmModeFB2 *fb2)
: fb2 { fb2 }, fb_id { fb2->fb_id }, width { fb2->width }, height { fb2->height } {
wrapper_fb(drmModeFB2 *fb2):
fb2 { fb2 }, fb_id { fb2->fb_id }, width { fb2->width }, height { fb2->height } {
pixel_format = fb2->pixel_format;
modifier = (fb2->flags & DRM_MODE_FB_MODIFIERS) ? fb2->modifier : DRM_FORMAT_MOD_INVALID;
@ -107,7 +107,8 @@ using conn_type_count_t = std::map<std::uint32_t, std::uint32_t>;
static int env_width;
static int env_height;
std::string_view plane_type(std::uint64_t val) {
std::string_view
plane_type(std::uint64_t val) {
switch (val) {
case DRM_PLANE_TYPE_OVERLAY:
return "DRM_PLANE_TYPE_OVERLAY"sv;
@ -149,7 +150,8 @@ struct card_descriptor_t {
static std::vector<card_descriptor_t> card_descriptors;
static std::uint32_t from_view(const std::string_view &string) {
static std::uint32_t
from_view(const std::string_view &string) {
#define _CONVERT(x, y) \
if (string == x) return DRM_MODE_CONNECTOR_##y
@ -174,15 +176,16 @@ static std::uint32_t from_view(const std::string_view &string) {
class plane_it_t: public round_robin_util::it_wrap_t<plane_t::element_type, plane_it_t> {
public:
plane_it_t(int fd, std::uint32_t *plane_p, std::uint32_t *end)
: fd { fd }, plane_p { plane_p }, end { end } {
plane_it_t(int fd, std::uint32_t *plane_p, std::uint32_t *end):
fd { fd }, plane_p { plane_p }, end { end } {
inc();
}
plane_it_t(int fd, std::uint32_t *end)
: fd { fd }, plane_p { end }, end { end } {}
plane_it_t(int fd, std::uint32_t *end):
fd { fd }, plane_p { end }, end { end } {}
void inc() {
void
inc() {
this->plane.reset();
for (; plane_p != end; ++plane_p) {
@ -204,11 +207,13 @@ public:
}
}
bool eq(const plane_it_t &other) const {
bool
eq(const plane_it_t &other) const {
return plane_p == other.plane_p;
}
plane_t::pointer get() {
plane_t::pointer
get() {
return plane.get();
}
@ -223,7 +228,8 @@ class card_t {
public:
using connector_interal_t = util::safe_ptr<drmModeConnector, drmModeFreeConnector>;
int init(const char *path) {
int
init(const char *path) {
cap_sys_admin admin;
fd.el = open(path, O_RDWR);
@ -250,7 +256,8 @@ public:
return 0;
}
fb_t fb(plane_t::pointer plane) {
fb_t
fb(plane_t::pointer plane) {
cap_sys_admin admin;
auto fb2 = drmModeGetFB2(fd.el, plane->fb_id);
@ -266,19 +273,23 @@ public:
return nullptr;
}
crtc_t crtc(std::uint32_t id) {
crtc_t
crtc(std::uint32_t id) {
return drmModeGetCrtc(fd.el, id);
}
encoder_t encoder(std::uint32_t id) {
encoder_t
encoder(std::uint32_t id) {
return drmModeGetEncoder(fd.el, id);
}
res_t res() {
res_t
res() {
return drmModeGetResources(fd.el);
}
bool is_cursor(std::uint32_t plane_id) {
bool
is_cursor(std::uint32_t plane_id) {
auto props = plane_props(plane_id);
for (auto &[prop, val] : props) {
if (prop->name == "type"sv) {
@ -294,7 +305,8 @@ public:
return false;
}
std::uint32_t get_panel_orientation(std::uint32_t plane_id) {
std::uint32_t
get_panel_orientation(std::uint32_t plane_id) {
auto props = plane_props(plane_id);
for (auto &[prop, val] : props) {
if (prop->name == "rotation"sv) {
@ -306,11 +318,13 @@ public:
return DRM_MODE_ROTATE_0;
}
connector_interal_t connector(std::uint32_t id) {
connector_interal_t
connector(std::uint32_t id) {
return drmModeGetConnector(fd.el, id);
}
std::vector<connector_t> monitors(conn_type_count_t &conn_type_count) {
std::vector<connector_t>
monitors(conn_type_count_t &conn_type_count) {
auto resources = res();
if (!resources) {
BOOST_LOG(error) << "Couldn't get connector resources"sv;
@ -343,7 +357,8 @@ public:
return monitors;
}
file_t handleFD(std::uint32_t handle) {
file_t
handleFD(std::uint32_t handle) {
file_t fb_fd;
auto status = drmPrimeHandleToFD(fd.el, handle, 0 /* flags */, &fb_fd.el);
@ -354,7 +369,8 @@ public:
return fb_fd;
}
std::vector<std::pair<prop_t, std::uint64_t>> props(std::uint32_t id, std::uint32_t type) {
std::vector<std::pair<prop_t, std::uint64_t>>
props(std::uint32_t id, std::uint32_t type) {
obj_prop_t obj_prop = drmModeObjectGetProperties(fd.el, id, type);
std::vector<std::pair<prop_t, std::uint64_t>> props;
@ -367,40 +383,47 @@ public:
return props;
}
std::vector<std::pair<prop_t, std::uint64_t>> plane_props(std::uint32_t id) {
std::vector<std::pair<prop_t, std::uint64_t>>
plane_props(std::uint32_t id) {
return props(id, DRM_MODE_OBJECT_PLANE);
}
std::vector<std::pair<prop_t, std::uint64_t>> crtc_props(std::uint32_t id) {
std::vector<std::pair<prop_t, std::uint64_t>>
crtc_props(std::uint32_t id) {
return props(id, DRM_MODE_OBJECT_CRTC);
}
std::vector<std::pair<prop_t, std::uint64_t>> connector_props(std::uint32_t id) {
std::vector<std::pair<prop_t, std::uint64_t>>
connector_props(std::uint32_t id) {
return props(id, DRM_MODE_OBJECT_CONNECTOR);
}
plane_t operator[](std::uint32_t index) {
plane_t
operator[](std::uint32_t index) {
return drmModeGetPlane(fd.el, plane_res->planes[index]);
}
std::uint32_t count() {
std::uint32_t
count() {
return plane_res->count_planes;
}
plane_it_t begin() const {
plane_it_t
begin() const {
return plane_it_t { fd.el, plane_res->planes, plane_res->planes + plane_res->count_planes };
}
plane_it_t end() const {
plane_it_t
end() const {
return plane_it_t { fd.el, plane_res->planes + plane_res->count_planes };
}
file_t fd;
plane_res_t plane_res;
};
std::map<std::uint32_t, monitor_t> map_crtc_to_monitor(const std::vector<connector_t> &connectors) {
std::map<std::uint32_t, monitor_t>
map_crtc_to_monitor(const std::vector<connector_t> &connectors) {
std::map<std::uint32_t, monitor_t> result;
for (auto &connector : connectors) {
@ -421,7 +444,8 @@ struct kms_img_t : public img_t {
}
};
void print(plane_t::pointer plane, fb_t::pointer fb, crtc_t::pointer crtc) {
void
print(plane_t::pointer plane, fb_t::pointer fb, crtc_t::pointer crtc) {
if (crtc) {
BOOST_LOG(debug) << "crtc("sv << crtc->x << ", "sv << crtc->y << ')';
BOOST_LOG(debug) << "crtc("sv << crtc->width << ", "sv << crtc->height << ')';
@ -455,9 +479,11 @@ void print(plane_t::pointer plane, fb_t::pointer fb, crtc_t::pointer crtc) {
class display_t: public platf::display_t {
public:
display_t(mem_type_e mem_type) : platf::display_t(), mem_type { mem_type } {}
display_t(mem_type_e mem_type):
platf::display_t(), mem_type { mem_type } {}
int init(const std::string &display_name, const ::video::config_t &config) {
int
init(const std::string &display_name, const ::video::config_t &config) {
delay = std::chrono::nanoseconds { 1s } / config.framerate;
int monitor_index = util::from_view(display_name);
@ -593,7 +619,8 @@ public:
return 0;
}
inline capture_e refresh(file_t *file, egl::surface_descriptor_t *sd) {
inline capture_e
refresh(file_t *file, egl::surface_descriptor_t *sd) {
plane_t plane = drmModeGetPlane(card.fd.el, plane_id);
auto fb = card.fb(plane.get());
@ -660,9 +687,11 @@ public:
class display_ram_t: public display_t {
public:
display_ram_t(mem_type_e mem_type) : display_t(mem_type) {}
display_ram_t(mem_type_e mem_type):
display_t(mem_type) {}
int init(const std::string &display_name, const ::video::config_t &config) {
int
init(const std::string &display_name, const ::video::config_t &config) {
if (!gbm::create_device) {
BOOST_LOG(warning) << "libgbm not initialized"sv;
return -1;
@ -693,7 +722,8 @@ public:
return 0;
}
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -728,7 +758,8 @@ public:
return capture_e::ok;
}
std::shared_ptr<hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override {
std::shared_ptr<hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) override {
if (mem_type == mem_type_e::vaapi) {
return va::make_hwdevice(width, height, false);
}
@ -736,7 +767,8 @@ public:
return std::make_shared<hwdevice_t>();
}
capture_e snapshot(img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
capture_e
snapshot(img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
file_t fb_fd[4];
egl::surface_descriptor_t sd;
@ -770,7 +802,8 @@ public:
return capture_e::ok;
}
std::shared_ptr<img_t> alloc_img() override {
std::shared_ptr<img_t>
alloc_img() override {
auto img = std::make_shared<kms_img_t>();
img->width = width;
img->height = height;
@ -781,7 +814,8 @@ public:
return img;
}
int dummy_img(platf::img_t *img) override {
int
dummy_img(platf::img_t *img) override {
return 0;
}
@ -792,9 +826,11 @@ public:
class display_vram_t: public display_t {
public:
display_vram_t(mem_type_e mem_type) : display_t(mem_type) {}
display_vram_t(mem_type_e mem_type):
display_t(mem_type) {}
std::shared_ptr<hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override {
std::shared_ptr<hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) override {
if (mem_type == mem_type_e::vaapi) {
return va::make_hwdevice(width, height, dup(card.fd.el), img_offset_x, img_offset_y, true);
}
@ -803,7 +839,8 @@ public:
return nullptr;
}
std::shared_ptr<img_t> alloc_img() override {
std::shared_ptr<img_t>
alloc_img() override {
auto img = std::make_shared<egl::img_descriptor_t>();
img->serial = std::numeric_limits<decltype(img->serial)>::max();
@ -816,11 +853,13 @@ public:
return img;
}
int dummy_img(platf::img_t *img) override {
int
dummy_img(platf::img_t *img) override {
return snapshot(img, 1s, false) != capture_e::ok;
}
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) {
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -855,7 +894,8 @@ public:
return capture_e::ok;
}
capture_e snapshot(img_t *img_out_base, std::chrono::milliseconds /* timeout */, bool cursor) {
capture_e
snapshot(img_t *img_out_base, std::chrono::milliseconds /* timeout */, bool cursor) {
file_t fb_fd[4];
auto img = (egl::img_descriptor_t *) img_out_base;
@ -888,7 +928,8 @@ public:
return capture_e::ok;
}
int init(const std::string &display_name, const ::video::config_t &config) {
int
init(const std::string &display_name, const ::video::config_t &config) {
if (display_t::init(display_name, config)) {
return -1;
}
@ -908,7 +949,8 @@ public:
} // namespace kms
std::shared_ptr<display_t> kms_display(mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
std::shared_ptr<display_t>
kms_display(mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
if (hwdevice_type == mem_type_e::vaapi) {
auto disp = std::make_shared<kms::display_vram_t>(hwdevice_type);
@ -928,7 +970,6 @@ std::shared_ptr<display_t> kms_display(mem_type_e hwdevice_type, const std::stri
return disp;
}
/**
* On Wayland, it's not possible to determine the position of the monitor on the desktop with KMS.
* Wayland does allow applications to query attached monitors on the desktop,
@ -939,7 +980,8 @@ std::shared_ptr<display_t> kms_display(mem_type_e hwdevice_type, const std::stri
*
* This is an ugly hack :(
*/
void correlate_to_wayland(std::vector<kms::card_descriptor_t> &cds) {
void
correlate_to_wayland(std::vector<kms::card_descriptor_t> &cds) {
auto monitors = wl::monitors();
for (auto &monitor : monitors) {
@ -990,7 +1032,8 @@ void correlate_to_wayland(std::vector<kms::card_descriptor_t> &cds) {
}
// A list of names of displays accepted as display_name
std::vector<std::string> kms_display_names() {
std::vector<std::string>
kms_display_names() {
int count = 0;
if (!fs::exists("/dev/dri")) {

View file

@ -37,7 +37,8 @@ namespace bp = boost::process;
window_system_e window_system;
namespace dyn {
void *handle(const std::vector<const char *> &libs) {
void *
handle(const std::vector<const char *> &libs) {
void *handle;
for (auto lib : libs) {
@ -60,7 +61,8 @@ void *handle(const std::vector<const char *> &libs) {
return nullptr;
}
int load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict) {
int
load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict) {
int err = 0;
for (auto &func : funcs) {
TUPLE_2D_REF(fn, name, func);
@ -80,7 +82,8 @@ int load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &f
namespace platf {
using ifaddr_t = util::safe_ptr<ifaddrs, freeifaddrs>;
ifaddr_t get_ifaddrs() {
ifaddr_t
get_ifaddrs() {
ifaddrs *p { nullptr };
getifaddrs(&p);
@ -88,7 +91,8 @@ ifaddr_t get_ifaddrs() {
return ifaddr_t { p };
}
fs::path appdata() {
fs::path
appdata() {
const char *homedir;
if ((homedir = getenv("HOME")) == nullptr) {
homedir = getpwuid(geteuid())->pw_dir;
@ -97,7 +101,8 @@ fs::path appdata() {
return fs::path { homedir } / ".config/sunshine"sv;
}
std::string from_sockaddr(const sockaddr *const ip_addr) {
std::string
from_sockaddr(const sockaddr *const ip_addr) {
char data[INET6_ADDRSTRLEN];
auto family = ip_addr->sa_family;
@ -114,7 +119,8 @@ std::string from_sockaddr(const sockaddr *const ip_addr) {
return std::string { data };
}
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_addr) {
std::pair<std::uint16_t, std::string>
from_sockaddr_ex(const sockaddr *const ip_addr) {
char data[INET6_ADDRSTRLEN];
auto family = ip_addr->sa_family;
@ -134,7 +140,8 @@ std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_
return { port, std::string { data } };
}
std::string get_mac_address(const std::string_view &address) {
std::string
get_mac_address(const std::string_view &address) {
auto ifaddrs = get_ifaddrs();
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
if (pos->ifa_addr && address == from_sockaddr(pos->ifa_addr)) {
@ -151,7 +158,8 @@ std::string get_mac_address(const std::string_view &address) {
return "00:00:00:00:00:00"s;
}
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
bp::child
run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
if (!group) {
if (!file) {
@ -171,29 +179,35 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
}
}
void adjust_thread_priority(thread_priority_e priority) {
void
adjust_thread_priority(thread_priority_e priority) {
// Unimplemented
}
void streaming_will_start() {
void
streaming_will_start() {
// Nothing to do
}
void streaming_will_stop() {
void
streaming_will_stop() {
// Nothing to do
}
bool restart_supported() {
bool
restart_supported() {
// Restart not supported yet
return false;
}
bool restart() {
bool
restart() {
// Restart not supported yet
return false;
}
bool send_batch(batched_send_info_t &send_info) {
bool
send_batch(batched_send_info_t &send_info) {
auto sockfd = (int) send_info.native_socket;
// Convert the target address into a sockaddr
@ -349,7 +363,8 @@ bool send_batch(batched_send_info_t &send_info) {
class qos_t: public deinit_t {
public:
qos_t(int sockfd, int level, int option) : sockfd(sockfd), level(level), option(option) {}
qos_t(int sockfd, int level, int option):
sockfd(sockfd), level(level), option(option) {}
virtual ~qos_t() {
int reset_val = -1;
@ -364,7 +379,8 @@ private:
int option;
};
std::unique_ptr<deinit_t> enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
std::unique_ptr<deinit_t>
enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
int sockfd = (int) native_socket;
int level;
@ -423,42 +439,55 @@ enum source_e : std::size_t {
static std::bitset<source::MAX_FLAGS> sources;
#ifdef SUNSHINE_BUILD_CUDA
std::vector<std::string> nvfbc_display_names();
std::shared_ptr<display_t> nvfbc_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
std::vector<std::string>
nvfbc_display_names();
std::shared_ptr<display_t>
nvfbc_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
bool verify_nvfbc() {
bool
verify_nvfbc() {
return !nvfbc_display_names().empty();
}
#endif
#ifdef SUNSHINE_BUILD_WAYLAND
std::vector<std::string> wl_display_names();
std::shared_ptr<display_t> wl_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
std::vector<std::string>
wl_display_names();
std::shared_ptr<display_t>
wl_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
bool verify_wl() {
bool
verify_wl() {
return window_system == window_system_e::WAYLAND && !wl_display_names().empty();
}
#endif
#ifdef SUNSHINE_BUILD_DRM
std::vector<std::string> kms_display_names();
std::shared_ptr<display_t> kms_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
std::vector<std::string>
kms_display_names();
std::shared_ptr<display_t>
kms_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
bool verify_kms() {
bool
verify_kms() {
return !kms_display_names().empty();
}
#endif
#ifdef SUNSHINE_BUILD_X11
std::vector<std::string> x11_display_names();
std::shared_ptr<display_t> x11_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
std::vector<std::string>
x11_display_names();
std::shared_ptr<display_t>
x11_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config);
bool verify_x11() {
bool
verify_x11() {
return window_system == window_system_e::X11 && !x11_display_names().empty();
}
#endif
std::vector<std::string> display_names(mem_type_e hwdevice_type) {
std::vector<std::string>
display_names(mem_type_e hwdevice_type) {
#ifdef SUNSHINE_BUILD_CUDA
// display using NvFBC only supports mem_type_e::cuda
if (sources[source::NVFBC] && hwdevice_type == mem_type_e::cuda) return nvfbc_display_names();
@ -475,7 +504,8 @@ std::vector<std::string> display_names(mem_type_e hwdevice_type) {
return {};
}
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t>
display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
#ifdef SUNSHINE_BUILD_CUDA
if (sources[source::NVFBC] && hwdevice_type == mem_type_e::cuda) {
BOOST_LOG(info) << "Screencasting with NvFBC"sv;
@ -504,7 +534,8 @@ std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &
return nullptr;
}
std::unique_ptr<deinit_t> init() {
std::unique_ptr<deinit_t>
init() {
// These are allowed to fail.
gbm::init();
va::init();

View file

@ -23,8 +23,10 @@ extern window_system_e window_system;
namespace dyn {
typedef void (*apiproc)(void);
int load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict = true);
void *handle(const std::vector<const char *> &libs);
int
load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict = true);
void *
handle(const std::vector<const char *> &libs);
} // namespace dyn

View file

@ -195,8 +195,8 @@ simple_poll_quit_fn simple_poll_quit;
simple_poll_new_fn simple_poll_new;
simple_poll_free_fn simple_poll_free;
int init_common() {
int
init_common() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -229,7 +229,8 @@ int init_common() {
return 0;
}
int init_client() {
int
init_client() {
if (init_common()) {
return -1;
}
@ -270,7 +271,8 @@ int init_client() {
namespace platf::publish {
template <class T>
void free(T *p) {
void
free(T *p) {
avahi::free(p);
}
@ -286,9 +288,11 @@ client_t client;
ptr_t<char> name;
void create_services(avahi::Client *c);
void
create_services(avahi::Client *c);
void entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, void *) {
void
entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, void *) {
group = g;
switch (state) {
@ -311,7 +315,8 @@ void entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, vo
}
}
void create_services(avahi::Client *c) {
void
create_services(avahi::Client *c) {
int ret;
auto fg = util::fail_guard([]() {
@ -366,7 +371,8 @@ void create_services(avahi::Client *c) {
fg.disable();
}
void client_callback(avahi::Client *c, avahi::ClientState state, void *) {
void
client_callback(avahi::Client *c, avahi::ClientState state, void *) {
switch (state) {
case avahi::CLIENT_S_RUNNING:
create_services(c);
@ -388,7 +394,8 @@ class deinit_t : public ::platf::deinit_t {
public:
std::thread poll_thread;
deinit_t(std::thread poll_thread) : poll_thread { std::move(poll_thread) } {}
deinit_t(std::thread poll_thread):
poll_thread { std::move(poll_thread) } {}
~deinit_t() override {
if (avahi::simple_poll_quit && poll) {
@ -401,7 +408,8 @@ public:
}
};
[[nodiscard]] std::unique_ptr<::platf::deinit_t> start() {
[[nodiscard]] std::unique_ptr<::platf::deinit_t>
start() {
if (avahi::init_client()) {
return nullptr;
}

View file

@ -9,7 +9,8 @@ extern "C" {
#if !VA_CHECK_VERSION(1, 9, 0)
/* vaSyncBuffer stub allows Sunshine built against libva <2.9.0
to link against ffmpeg on libva 2.9.0 or later */
VAStatus vaSyncBuffer(
VAStatus
vaSyncBuffer(
VADisplay dpy,
VABufferID buf_id,
uint64_t timeout_ns) {
@ -193,7 +194,6 @@ enum class entry_e {
ProtectedContent = 14,
};
typedef VAStatus (*queryConfigEntrypoints_fn)(VADisplay dpy, profile_e profile, entry_e *entrypoint_list, int *num_entrypoints);
typedef int (*maxNumEntrypoints_fn)(VADisplay dpy);
typedef VADisplay (*getDisplayDRM_fn)(int fd);
@ -222,7 +222,8 @@ static exportSurfaceHandle_fn exportSurfaceHandle;
using display_t = util::dyn_safe_ptr_v2<void, VAStatus, &terminate>;
int init_main_va() {
int
init_main_va() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -255,7 +256,8 @@ int init_main_va() {
return 0;
}
int init() {
int
init() {
if (init_main_va()) {
return -1;
}
@ -284,11 +286,13 @@ int init() {
return 0;
}
int vaapi_make_hwdevice_ctx(platf::hwdevice_t *base, AVBufferRef **hw_device_buf);
int
vaapi_make_hwdevice_ctx(platf::hwdevice_t *base, AVBufferRef **hw_device_buf);
class va_t: public platf::hwdevice_t {
public:
int init(int in_width, int in_height, file_t &&render_device) {
int
init(int in_width, int in_height, file_t &&render_device) {
file = std::move(render_device);
if (!va::initialize || !gbm::create_device) {
@ -324,7 +328,8 @@ public:
return 0;
}
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
this->hwframe.reset(frame);
this->frame = frame;
@ -345,7 +350,6 @@ public:
va::EXPORT_SURFACE_WRITE_ONLY | va::EXPORT_SURFACE_COMPOSED_LAYERS,
&prime);
if (status) {
BOOST_LOG(error) << "Couldn't export va surface handle: ["sv << (int) surface << "]: "sv << va::errorStr(status);
return -1;
@ -390,7 +394,8 @@ public:
return 0;
}
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
sws.set_colorspace(colorspace, color_range);
}
@ -413,7 +418,8 @@ public:
class va_ram_t: public va_t {
public:
int convert(platf::img_t &img) override {
int
convert(platf::img_t &img) override {
sws.load_ram(img);
sws.convert(nv12->buf);
@ -423,7 +429,8 @@ public:
class va_vram_t: public va_t {
public:
int convert(platf::img_t &img) override {
int
convert(platf::img_t &img) override {
auto &descriptor = (egl::img_descriptor_t &) img;
if (descriptor.sequence > sequence) {
@ -446,7 +453,8 @@ public:
return 0;
}
int init(int in_width, int in_height, file_t &&render_device, int offset_x, int offset_y) {
int
init(int in_width, int in_height, file_t &&render_device, int offset_x, int offset_y) {
if (va_t::init(in_width, in_height, std::move(render_device))) {
return -1;
}
@ -499,11 +507,13 @@ typedef struct AVVAAPIDeviceContext {
unsigned int driver_quirks;
} AVVAAPIDeviceContext;
static void __log(void *level, const char *msg) {
static void
__log(void *level, const char *msg) {
BOOST_LOG(*(boost::log::sources::severity_logger<int> *) level) << msg;
}
int vaapi_make_hwdevice_ctx(platf::hwdevice_t *base, AVBufferRef **hw_device_buf) {
int
vaapi_make_hwdevice_ctx(platf::hwdevice_t *base, AVBufferRef **hw_device_buf) {
if (!va::initialize) {
BOOST_LOG(warning) << "libva not loaded"sv;
return -1;
@ -565,7 +575,8 @@ int vaapi_make_hwdevice_ctx(platf::hwdevice_t *base, AVBufferRef **hw_device_buf
return 0;
}
static bool query(display_t::pointer display, profile_e profile) {
static bool
query(display_t::pointer display, profile_e profile) {
std::vector<entry_e> entrypoints;
entrypoints.resize(maxNumEntrypoints(display));
@ -586,7 +597,8 @@ static bool query(display_t::pointer display, profile_e profile) {
return false;
}
bool validate(int fd) {
bool
validate(int fd) {
if (init()) {
return false;
}
@ -625,7 +637,8 @@ bool validate(int fd) {
return true;
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram) {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram) {
if (vram) {
auto egl = std::make_shared<va::va_vram_t>();
if (egl->init(width, height, std::move(card), offset_x, offset_y)) {
@ -645,7 +658,8 @@ std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, file_t &
}
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, int offset_x, int offset_y, bool vram) {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, int offset_x, int offset_y, bool vram) {
auto render_device = config::video.adapter_name.empty() ? "/dev/dri/renderD128" : config::video.adapter_name.c_str();
file_t file = open(render_device, O_RDWR);
@ -659,7 +673,8 @@ std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, int offs
return make_hwdevice(width, height, std::move(file), offset_x, offset_y, vram);
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, bool vram) {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, bool vram) {
return make_hwdevice(width, height, 0, 0, vram);
}
} // namespace va

View file

@ -15,13 +15,18 @@ namespace va {
* offset_y --> Vertical offset of the image in the texture
* file_t card --> The file descriptor of the render device used for encoding
*/
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, bool vram);
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, int offset_x, int offset_y, bool vram);
std::shared_ptr<platf::hwdevice_t> make_hwdevice(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram);
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, bool vram);
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, int offset_x, int offset_y, bool vram);
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(int width, int height, file_t &&card, int offset_x, int offset_y, bool vram);
// Ensure the render device pointed to by fd is capable of encoding h264 with the hevc_mode configured
bool validate(int fd);
bool
validate(int fd);
int init();
int
init();
} // namespace va
#endif

View file

@ -23,13 +23,15 @@ namespace wl {
// Helper to call C++ method from wayland C callback
template <class T, class Method, Method m, class... Params>
static auto classCall(void *data, Params... params) -> decltype(((*reinterpret_cast<T *>(data)).*m)(params...)) {
static auto
classCall(void *data, Params... params) -> decltype(((*reinterpret_cast<T *>(data)).*m)(params...)) {
return ((*reinterpret_cast<T *>(data)).*m)(params...);
}
#define CLASS_CALL(c, m) classCall<c, decltype(&c::m), &c::m>
int display_t::init(const char *display_name) {
int
display_t::init(const char *display_name) {
if (!display_name) {
display_name = std::getenv("WAYLAND_DISPLAY");
}
@ -50,16 +52,18 @@ int display_t::init(const char *display_name) {
return 0;
}
void display_t::roundtrip() {
void
display_t::roundtrip() {
wl_display_roundtrip(display_internal.get());
}
wl_registry *display_t::registry() {
wl_registry *
display_t::registry() {
return wl_display_get_registry(display_internal.get());
}
inline monitor_t::monitor_t(wl_output *output)
: output { output }, listener {
inline monitor_t::monitor_t(wl_output *output):
output { output }, listener {
&CLASS_CALL(monitor_t, xdg_position),
&CLASS_CALL(monitor_t, xdg_size),
&CLASS_CALL(monitor_t, xdg_done),
@ -67,52 +71,62 @@ inline monitor_t::monitor_t(wl_output *output)
&CLASS_CALL(monitor_t, xdg_description)
} {}
inline void monitor_t::xdg_name(zxdg_output_v1 *, const char *name) {
inline void
monitor_t::xdg_name(zxdg_output_v1 *, const char *name) {
this->name = name;
BOOST_LOG(info) << "Name: "sv << this->name;
}
void monitor_t::xdg_description(zxdg_output_v1 *, const char *description) {
void
monitor_t::xdg_description(zxdg_output_v1 *, const char *description) {
this->description = description;
BOOST_LOG(info) << "Found monitor: "sv << this->description;
}
void monitor_t::xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y) {
void
monitor_t::xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y) {
viewport.offset_x = x;
viewport.offset_y = y;
BOOST_LOG(info) << "Offset: "sv << x << 'x' << y;
}
void monitor_t::xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height) {
void
monitor_t::xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height) {
viewport.width = width;
viewport.height = height;
BOOST_LOG(info) << "Resolution: "sv << width << 'x' << height;
}
void monitor_t::xdg_done(zxdg_output_v1 *) {
void
monitor_t::xdg_done(zxdg_output_v1 *) {
BOOST_LOG(info) << "All info about monitor ["sv << name << "] has been send"sv;
}
void monitor_t::listen(zxdg_output_manager_v1 *output_manager) {
void
monitor_t::listen(zxdg_output_manager_v1 *output_manager) {
auto xdg_output = zxdg_output_manager_v1_get_xdg_output(output_manager, output);
zxdg_output_v1_add_listener(xdg_output, &listener, this);
}
interface_t::interface_t() noexcept
: output_manager { nullptr }, listener {
:
output_manager { nullptr },
listener {
&CLASS_CALL(interface_t, add_interface),
&CLASS_CALL(interface_t, del_interface)
} {}
void interface_t::listen(wl_registry *registry) {
void
interface_t::listen(wl_registry *registry) {
wl_registry_add_listener(registry, &listener, this);
}
void interface_t::add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version) {
void
interface_t::add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version) {
BOOST_LOG(debug) << "Available interface: "sv << interface << '(' << id << ") version "sv << version;
if (!std::strcmp(interface, wl_output_interface.name)) {
@ -135,12 +149,13 @@ void interface_t::add_interface(wl_registry *registry, std::uint32_t id, const c
}
}
void interface_t::del_interface(wl_registry *registry, uint32_t id) {
void
interface_t::del_interface(wl_registry *registry, uint32_t id) {
BOOST_LOG(info) << "Delete: "sv << id;
}
dmabuf_t::dmabuf_t()
: status { READY }, frames {}, current_frame { &frames[0] }, listener {
dmabuf_t::dmabuf_t():
status { READY }, frames {}, current_frame { &frames[0] }, listener {
&CLASS_CALL(dmabuf_t, frame),
&CLASS_CALL(dmabuf_t, object),
&CLASS_CALL(dmabuf_t, ready),
@ -148,7 +163,8 @@ dmabuf_t::dmabuf_t()
} {
}
void dmabuf_t::listen(zwlr_export_dmabuf_manager_v1 *dmabuf_manager, wl_output *output, bool blend_cursor) {
void
dmabuf_t::listen(zwlr_export_dmabuf_manager_v1 *dmabuf_manager, wl_output *output, bool blend_cursor) {
auto frame = zwlr_export_dmabuf_manager_v1_capture_output(dmabuf_manager, blend_cursor, output);
zwlr_export_dmabuf_frame_v1_add_listener(frame, &listener, this);
@ -161,7 +177,8 @@ dmabuf_t::~dmabuf_t() {
}
}
void dmabuf_t::frame(
void
dmabuf_t::frame(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t width, std::uint32_t height,
std::uint32_t x, std::uint32_t y,
@ -177,7 +194,8 @@ void dmabuf_t::frame(
next_frame->sd.modifier = (((std::uint64_t) high) << 32) | low;
}
void dmabuf_t::object(
void
dmabuf_t::object(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t index,
std::int32_t fd,
@ -192,10 +210,10 @@ void dmabuf_t::object(
next_frame->sd.offsets[plane_index] = offset;
}
void dmabuf_t::ready(
void
dmabuf_t::ready(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec) {
zwlr_export_dmabuf_frame_v1_destroy(frame);
current_frame->destroy();
@ -204,10 +222,10 @@ void dmabuf_t::ready(
status = READY;
}
void dmabuf_t::cancel(
void
dmabuf_t::cancel(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t reason) {
zwlr_export_dmabuf_frame_v1_destroy(frame);
auto next_frame = get_next_frame();
@ -216,7 +234,8 @@ void dmabuf_t::cancel(
status = REINIT;
}
void frame_t::destroy() {
void
frame_t::destroy() {
for (auto x = 0; x < 4; ++x) {
if (sd.fds[x] >= 0) {
close(sd.fds[x]);
@ -231,7 +250,8 @@ frame_t::frame_t() {
std::fill_n(sd.fds, 4, -1);
};
std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name) {
std::vector<std::unique_ptr<monitor_t>>
monitors(const char *display_name) {
display_t display;
if (display.init(display_name)) {
@ -257,13 +277,15 @@ std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name) {
return std::move(interface.monitors);
}
static bool validate() {
static bool
validate() {
display_t display;
return display.init() == 0;
}
int init() {
int
init() {
static bool validated = validate();
return !validated;

View file

@ -24,7 +24,8 @@ public:
frame_t();
egl::surface_descriptor_t sd;
void destroy();
void
destroy();
};
class dmabuf_t {
@ -38,16 +39,20 @@ public:
dmabuf_t(dmabuf_t &&) = delete;
dmabuf_t(const dmabuf_t &) = delete;
dmabuf_t &operator=(const dmabuf_t &) = delete;
dmabuf_t &operator=(dmabuf_t &&) = delete;
dmabuf_t &
operator=(const dmabuf_t &) = delete;
dmabuf_t &
operator=(dmabuf_t &&) = delete;
dmabuf_t();
void listen(zwlr_export_dmabuf_manager_v1 *dmabuf_manager, wl_output *output, bool blend_cursor = false);
void
listen(zwlr_export_dmabuf_manager_v1 *dmabuf_manager, wl_output *output, bool blend_cursor = false);
~dmabuf_t();
void frame(
void
frame(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t width, std::uint32_t height,
std::uint32_t x, std::uint32_t y,
@ -56,7 +61,8 @@ public:
std::uint32_t high, std::uint32_t low,
std::uint32_t obj_count);
void object(
void
object(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t index,
std::int32_t fd,
@ -65,15 +71,18 @@ public:
std::uint32_t stride,
std::uint32_t plane_index);
void ready(
void
ready(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec);
void cancel(
void
cancel(
zwlr_export_dmabuf_frame_v1 *frame,
std::uint32_t reason);
inline frame_t *get_next_frame() {
inline frame_t *
get_next_frame() {
return current_frame == &frames[0] ? &frames[1] : &frames[0];
}
@ -90,18 +99,26 @@ public:
monitor_t(monitor_t &&) = delete;
monitor_t(const monitor_t &) = delete;
monitor_t &operator=(const monitor_t &) = delete;
monitor_t &operator=(monitor_t &&) = delete;
monitor_t &
operator=(const monitor_t &) = delete;
monitor_t &
operator=(monitor_t &&) = delete;
monitor_t(wl_output *output);
void xdg_name(zxdg_output_v1 *, const char *name);
void xdg_description(zxdg_output_v1 *, const char *description);
void xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y);
void xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height);
void xdg_done(zxdg_output_v1 *);
void
xdg_name(zxdg_output_v1 *, const char *name);
void
xdg_description(zxdg_output_v1 *, const char *description);
void
xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y);
void
xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height);
void
xdg_done(zxdg_output_v1 *);
void listen(zxdg_output_manager_v1 *output_manager);
void
listen(zxdg_output_manager_v1 *output_manager);
wl_output *output;
@ -129,25 +146,31 @@ public:
interface_t(interface_t &&) = delete;
interface_t(const interface_t &) = delete;
interface_t &operator=(const interface_t &) = delete;
interface_t &operator=(interface_t &&) = delete;
interface_t &
operator=(const interface_t &) = delete;
interface_t &
operator=(interface_t &&) = delete;
interface_t() noexcept;
void listen(wl_registry *registry);
void
listen(wl_registry *registry);
std::vector<std::unique_ptr<monitor_t>> monitors;
zwlr_export_dmabuf_manager_v1 *dmabuf_manager;
zxdg_output_manager_v1 *output_manager;
bool operator[](interface_e bit) const {
bool
operator[](interface_e bit) const {
return interface[bit];
}
private:
void add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version);
void del_interface(wl_registry *registry, uint32_t id);
void
add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version);
void
del_interface(wl_registry *registry, uint32_t id);
std::bitset<MAX_INTERFACES> interface;
@ -160,16 +183,20 @@ public:
* Initialize display with display_name
* If display_name == nullptr -> display_name = std::getenv("WAYLAND_DISPLAY")
*/
int init(const char *display_name = nullptr);
int
init(const char *display_name = nullptr);
// Roundtrip with Wayland connection
void roundtrip();
void
roundtrip();
// Get the registry associated with the display
// No need to manually free the registry
wl_registry *registry();
wl_registry *
registry();
inline display_internal_t::pointer get() {
inline display_internal_t::pointer
get() {
return display_internal.get();
}
@ -177,9 +204,11 @@ private:
display_internal_t display_internal;
};
std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr);
std::vector<std::unique_ptr<monitor_t>>
monitors(const char *display_name = nullptr);
int init();
int
init();
} // namespace wl
#else
@ -192,12 +221,15 @@ public:
monitor_t(monitor_t &&) = delete;
monitor_t(const monitor_t &) = delete;
monitor_t &operator=(const monitor_t &) = delete;
monitor_t &operator=(monitor_t &&) = delete;
monitor_t &
operator=(const monitor_t &) = delete;
monitor_t &
operator=(monitor_t &&) = delete;
monitor_t(wl_output *output);
void listen(zxdg_output_manager_v1 *output_manager);
void
listen(zxdg_output_manager_v1 *output_manager);
wl_output *output;
@ -207,9 +239,11 @@ public:
platf::touch_port_t viewport;
};
inline std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr) { return {}; }
inline std::vector<std::unique_ptr<monitor_t>>
monitors(const char *display_name = nullptr) { return {}; }
inline int init() { return -1; }
inline int
init() { return -1; }
} // namespace wl
#endif

View file

@ -19,7 +19,8 @@ struct img_t : public platf::img_t {
class wlr_t: public platf::display_t {
public:
int init(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
int
init(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
delay = std::chrono::nanoseconds { 1s } / config.framerate;
mem_type = hwdevice_type;
@ -73,11 +74,13 @@ public:
return 0;
}
int dummy_img(platf::img_t *img) override {
int
dummy_img(platf::img_t *img) override {
return 0;
}
inline platf::capture_e snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
inline platf::capture_e
snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
auto to = std::chrono::steady_clock::now() + timeout;
dmabuf.listen(interface.dmabuf_manager, output, cursor);
@ -95,7 +98,6 @@ public:
dmabuf.status == dmabuf_t::REINIT ||
current_frame->sd.width != width ||
current_frame->sd.height != height) {
return platf::capture_e::reinit;
}
@ -115,7 +117,8 @@ public:
class wlr_ram_t: public wlr_t {
public:
platf::capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
platf::capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -149,7 +152,8 @@ public:
return platf::capture_e::ok;
}
platf::capture_e snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
platf::capture_e
snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
auto status = wlr_t::snapshot(img_out_base, timeout, cursor);
if (status != platf::capture_e::ok) {
return status;
@ -176,7 +180,8 @@ public:
return platf::capture_e::ok;
}
int init(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
int
init(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
if (wlr_t::init(hwdevice_type, display_name, config)) {
return -1;
}
@ -196,7 +201,8 @@ public:
return 0;
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(platf::pix_fmt_e pix_fmt) override {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(platf::pix_fmt_e pix_fmt) override {
if (mem_type == platf::mem_type_e::vaapi) {
return va::make_hwdevice(width, height, false);
}
@ -204,7 +210,8 @@ public:
return std::make_shared<platf::hwdevice_t>();
}
std::shared_ptr<platf::img_t> alloc_img() override {
std::shared_ptr<platf::img_t>
alloc_img() override {
auto img = std::make_shared<img_t>();
img->width = width;
img->height = height;
@ -221,7 +228,8 @@ public:
class wlr_vram_t: public wlr_t {
public:
platf::capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
platf::capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<platf::img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -255,7 +263,8 @@ public:
return platf::capture_e::ok;
}
platf::capture_e snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
platf::capture_e
snapshot(platf::img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
auto status = wlr_t::snapshot(img_out_base, timeout, cursor);
if (status != platf::capture_e::ok) {
return status;
@ -277,7 +286,8 @@ public:
return platf::capture_e::ok;
}
std::shared_ptr<platf::img_t> alloc_img() override {
std::shared_ptr<platf::img_t>
alloc_img() override {
auto img = std::make_shared<egl::img_descriptor_t>();
img->sequence = 0;
@ -290,7 +300,8 @@ public:
return img;
}
std::shared_ptr<platf::hwdevice_t> make_hwdevice(platf::pix_fmt_e pix_fmt) override {
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(platf::pix_fmt_e pix_fmt) override {
if (mem_type == platf::mem_type_e::vaapi) {
return va::make_hwdevice(width, height, 0, 0, true);
}
@ -298,7 +309,8 @@ public:
return std::make_shared<platf::hwdevice_t>();
}
int dummy_img(platf::img_t *img) override {
int
dummy_img(platf::img_t *img) override {
return snapshot(img, 1000ms, false) != platf::capture_e::ok;
}
@ -308,7 +320,8 @@ public:
} // namespace wl
namespace platf {
std::shared_ptr<display_t> wl_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t>
wl_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
if (hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) {
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
return nullptr;
@ -331,7 +344,8 @@ std::shared_ptr<display_t> wl_display(mem_type_e hwdevice_type, const std::strin
return wlr;
}
std::vector<std::string> wl_display_names() {
std::vector<std::string>
wl_display_names() {
std::vector<std::string> display_names;
wl::display_t display;

View file

@ -30,8 +30,10 @@
using namespace std::literals;
namespace platf {
int load_xcb();
int load_x11();
int
load_xcb();
int
load_x11();
namespace x11 {
#define _FN(x, ret, args) \
@ -66,7 +68,8 @@ _FN(FreeScreenResources, void, (XRRScreenResources * resources));
_FN(FreeOutputInfo, void, (XRROutputInfo * outputInfo));
_FN(FreeCrtcInfo, void, (XRRCrtcInfo * crtcInfo));
static int init() {
static int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -100,7 +103,8 @@ static int init() {
namespace fix {
_FN(GetCursorImage, XFixesCursorImage *, (Display * dpy));
static int init() {
static int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -126,7 +130,8 @@ static int init() {
}
} // namespace fix
static int init() {
static int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -193,7 +198,8 @@ _FN(connect, xcb_connection_t *, (const char *displayname, int *screenp));
_FN(setup_roots_iterator, xcb_screen_iterator_t, (const xcb_setup_t *R));
_FN(generate_id, std::uint32_t, (xcb_connection_t * c));
int init_shm() {
int
init_shm() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -221,7 +227,8 @@ int init_shm() {
return 0;
}
int init() {
int
init() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -255,8 +262,10 @@ int init() {
#undef _FN
} // namespace xcb
void freeImage(XImage *);
void freeX(XFixesCursorImage *);
void
freeImage(XImage *);
void
freeX(XFixesCursorImage *);
using xcb_connect_t = util::dyn_safe_ptr<xcb_connection_t, &xcb::disconnect>;
using xcb_img_t = util::c_ptr<xcb_shm_get_image_reply_t>;
@ -270,9 +279,12 @@ using screen_res_t = util::dyn_safe_ptr<_XRRScreenResources, &x11::rr::FreeScre
class shm_id_t {
public:
shm_id_t() : id { -1 } {}
shm_id_t(int id) : id { id } {}
shm_id_t(shm_id_t &&other) noexcept : id(other.id) {
shm_id_t():
id { -1 } {}
shm_id_t(int id):
id { id } {}
shm_id_t(shm_id_t &&other) noexcept:
id(other.id) {
other.id = -1;
}
@ -287,10 +299,13 @@ public:
class shm_data_t {
public:
shm_data_t() : data { (void *)-1 } {}
shm_data_t(void *data) : data { data } {}
shm_data_t():
data { (void *) -1 } {}
shm_data_t(void *data):
data { data } {}
shm_data_t(shm_data_t &&other) noexcept : data(other.data) {
shm_data_t(shm_data_t &&other) noexcept:
data(other.data) {
other.data = (void *) -1;
}
@ -314,7 +329,8 @@ struct shm_img_t : public img_t {
}
};
static void blend_cursor(Display *display, img_t &img, int offsetX, int offsetY) {
static void
blend_cursor(Display *display, img_t &img, int offsetX, int offsetY) {
xcursor_t overlay { x11::fix::GetCursorImage(display) };
if (!overlay) {
@ -379,11 +395,13 @@ struct x11_attr_t : public display_t {
*/
// int env_width, env_height;
x11_attr_t(mem_type_e mem_type) : xdisplay { x11::OpenDisplay(nullptr) }, xwindow {}, xattr {}, mem_type { mem_type } {
x11_attr_t(mem_type_e mem_type):
xdisplay { x11::OpenDisplay(nullptr) }, xwindow {}, xattr {}, mem_type { mem_type } {
x11::InitThreads();
}
int init(const std::string &display_name, const ::video::config_t &config) {
int
init(const std::string &display_name, const ::video::config_t &config) {
if (!xdisplay) {
BOOST_LOG(error) << "Could not open X11 display"sv;
return -1;
@ -452,11 +470,13 @@ struct x11_attr_t : public display_t {
/**
* Called when the display attributes should change.
*/
void refresh() {
void
refresh() {
x11::GetWindowAttributes(xdisplay.get(), xwindow, &xattr); //Update xattr's
}
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -491,7 +511,8 @@ struct x11_attr_t : public display_t {
return capture_e::ok;
}
capture_e snapshot(img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
capture_e
snapshot(img_t *img_out_base, std::chrono::milliseconds timeout, bool cursor) {
refresh();
//The whole X server changed, so we must reinit everything
@ -516,11 +537,13 @@ struct x11_attr_t : public display_t {
return capture_e::ok;
}
std::shared_ptr<img_t> alloc_img() override {
std::shared_ptr<img_t>
alloc_img() override {
return std::make_shared<x11_img_t>();
}
std::shared_ptr<hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override {
std::shared_ptr<hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) override {
if (mem_type == mem_type_e::vaapi) {
return va::make_hwdevice(width, height, false);
}
@ -534,7 +557,8 @@ struct x11_attr_t : public display_t {
return std::make_shared<hwdevice_t>();
}
int dummy_img(img_t *img) override {
int
dummy_img(img_t *img) override {
snapshot(img, 0s, true);
return 0;
}
@ -552,13 +576,15 @@ struct shm_attr_t : public x11_attr_t {
task_pool_util::TaskPool::task_id_t refresh_task_id;
void delayed_refresh() {
void
delayed_refresh() {
refresh();
refresh_task_id = task_pool.pushDelayed(&shm_attr_t::delayed_refresh, 2s, this).task_id;
}
shm_attr_t(mem_type_e mem_type) : x11_attr_t(mem_type), shm_xdisplay { x11::OpenDisplay(nullptr) } {
shm_attr_t(mem_type_e mem_type):
x11_attr_t(mem_type), shm_xdisplay { x11::OpenDisplay(nullptr) } {
refresh_task_id = task_pool.pushDelayed(&shm_attr_t::delayed_refresh, 2s, this).task_id;
}
@ -567,7 +593,8 @@ struct shm_attr_t : public x11_attr_t {
;
}
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
auto next_frame = std::chrono::steady_clock::now();
while (img) {
@ -602,7 +629,8 @@ struct shm_attr_t : public x11_attr_t {
return capture_e::ok;
}
capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) {
capture_e
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) {
//The whole X server changed, so we must reinit everything
if (xattr.width != env_width || xattr.height != env_height) {
BOOST_LOG(warning) << "X dimensions changed in SHM mode, request reinit"sv;
@ -627,7 +655,8 @@ struct shm_attr_t : public x11_attr_t {
}
}
std::shared_ptr<img_t> alloc_img() override {
std::shared_ptr<img_t>
alloc_img() override {
auto img = std::make_shared<shm_img_t>();
img->width = width;
img->height = height;
@ -638,11 +667,13 @@ struct shm_attr_t : public x11_attr_t {
return img;
}
int dummy_img(platf::img_t *img) override {
int
dummy_img(platf::img_t *img) override {
return 0;
}
int init(const std::string &display_name, const ::video::config_t &config) {
int
init(const std::string &display_name, const ::video::config_t &config) {
if (x11_attr_t::init(display_name, config)) {
return 1;
}
@ -681,12 +712,14 @@ struct shm_attr_t : public x11_attr_t {
return 0;
}
std::uint32_t frame_size() {
std::uint32_t
frame_size() {
return width * height * 4;
}
};
std::shared_ptr<display_t> x11_display(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
std::shared_ptr<display_t>
x11_display(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
if (hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) {
BOOST_LOG(error) << "Could not initialize x11 display with the given hw device type"sv;
return nullptr;
@ -720,7 +753,8 @@ std::shared_ptr<display_t> x11_display(platf::mem_type_e hwdevice_type, const st
return x11_disp;
}
std::vector<std::string> x11_display_names() {
std::vector<std::string>
x11_display_names() {
if (load_x11() || load_xcb()) {
BOOST_LOG(error) << "Couldn't init x11 libraries"sv;
@ -756,21 +790,25 @@ std::vector<std::string> x11_display_names() {
return names;
}
void freeImage(XImage *p) {
void
freeImage(XImage *p) {
XDestroyImage(p);
}
void freeX(XFixesCursorImage *p) {
void
freeX(XFixesCursorImage *p) {
x11::Free(p);
}
int load_xcb() {
int
load_xcb() {
// This will be called once only
static int xcb_status = xcb::init_shm() || xcb::init();
return xcb_status;
}
int load_x11() {
int
load_x11() {
// This will be called once only
static int x11_status =
window_system == window_system_e::NONE ||
@ -780,7 +818,8 @@ int load_x11() {
}
namespace x11 {
std::optional<cursor_t> cursor_t::make() {
std::optional<cursor_t>
cursor_t::make() {
if (load_x11()) {
return std::nullopt;
}
@ -792,7 +831,8 @@ std::optional<cursor_t> cursor_t::make() {
return cursor;
}
void cursor_t::capture(egl::cursor_t &img) {
void
cursor_t::capture(egl::cursor_t &img) {
auto display = (xdisplay_t::pointer) ctx.get();
xcursor_t xcursor = fix::GetCursorImage(display);
@ -819,19 +859,23 @@ void cursor_t::capture(egl::cursor_t &img) {
img.serial = xcursor->cursor_serial;
}
void cursor_t::blend(img_t &img, int offsetX, int offsetY) {
void
cursor_t::blend(img_t &img, int offsetX, int offsetY) {
blend_cursor((xdisplay_t::pointer) ctx.get(), img, offsetX, offsetY);
}
xdisplay_t make_display() {
xdisplay_t
make_display() {
return OpenDisplay(nullptr);
}
void freeDisplay(_XDisplay *xdisplay) {
void
freeDisplay(_XDisplay *xdisplay) {
CloseDisplay(xdisplay);
}
void freeCursorCtx(cursor_ctx_t::pointer ctx) {
void
freeCursorCtx(cursor_ctx_t::pointer ctx) {
CloseDisplay((xdisplay_t::pointer) ctx);
}
} // namespace x11

View file

@ -17,17 +17,21 @@ namespace platf::x11 {
#ifdef SUNSHINE_BUILD_X11
struct cursor_ctx_raw_t;
void freeCursorCtx(cursor_ctx_raw_t *ctx);
void freeDisplay(_XDisplay *xdisplay);
void
freeCursorCtx(cursor_ctx_raw_t *ctx);
void
freeDisplay(_XDisplay *xdisplay);
using cursor_ctx_t = util::safe_ptr<cursor_ctx_raw_t, freeCursorCtx>;
using xdisplay_t = util::safe_ptr<_XDisplay, freeDisplay>;
class cursor_t {
public:
static std::optional<cursor_t> make();
static std::optional<cursor_t>
make();
void capture(egl::cursor_t &img);
void
capture(egl::cursor_t &img);
/**
* Capture and blend the cursor into the image
@ -35,25 +39,31 @@ public:
* img <-- destination image
* offsetX, offsetY <--- Top left corner of the virtual screen
*/
void blend(img_t &img, int offsetX, int offsetY);
void
blend(img_t &img, int offsetX, int offsetY);
cursor_ctx_t ctx;
};
xdisplay_t make_display();
xdisplay_t
make_display();
#else
// It's never something different from nullptr
util::safe_ptr<_XDisplay, std::default_delete<_XDisplay>>;
class cursor_t {
public:
static std::optional<cursor_t> make() { return std::nullopt; }
static std::optional<cursor_t>
make() { return std::nullopt; }
void capture(egl::cursor_t &) {}
void blend(img_t &, int, int) {}
void
capture(egl::cursor_t &) {}
void
blend(img_t &, int, int) {}
};
xdisplay_t make_display() { return nullptr; }
xdisplay_t
make_display() { return nullptr; }
#endif
} // namespace platf::x11

View file

@ -3,7 +3,6 @@
@implementation AVAudio
+ (NSArray<AVCaptureDevice *> *)microphones {
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:((NSOperatingSystemVersion) { 10, 15, 0 })]) {
// This will generate a warning about AVCaptureDeviceDiscoverySession being
// unavailable before macOS 10.15, but we have a guard to prevent it from

View file

@ -3,7 +3,6 @@
#import <AVFoundation/AVFoundation.h>
struct CaptureSession {
AVCaptureVideoDataOutput *output;
NSCondition *captureStopped;

View file

@ -163,7 +163,6 @@
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
FrameCallbackBlock callback = [self.captureCallbacks objectForKey:connection];
if (callback != nil) {

View file

@ -36,7 +36,8 @@ struct av_display_t : public display_t {
[av_capture release];
}
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override {
__block auto img_next = std::move(img);
auto signal = [av_capture capture:^(CMSampleBufferRef sampleBuffer) {
@ -76,11 +77,13 @@ struct av_display_t : public display_t {
return capture_e::ok;
}
std::shared_ptr<img_t> alloc_img() override {
std::shared_ptr<img_t>
alloc_img() override {
return std::make_shared<av_img_t>();
}
std::shared_ptr<hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override {
std::shared_ptr<hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) override {
if (pix_fmt == pix_fmt_e::yuv420p) {
av_capture.pixelFormat = kCVPixelFormatType_32BGRA;
@ -99,7 +102,8 @@ struct av_display_t : public display_t {
}
}
int dummy_img(img_t *img) override {
int
dummy_img(img_t *img) override {
auto signal = [av_capture capture:^(CMSampleBufferRef sampleBuffer) {
auto av_img = (av_img_t *) img;
@ -143,16 +147,19 @@ struct av_display_t : public display_t {
* width --> the intended capture width
* height --> the intended capture height
*/
static void setResolution(void *display, int width, int height) {
static void
setResolution(void *display, int width, int height) {
[static_cast<AVVideo *>(display) setFrameWidth:width frameHeight:height];
}
static void setPixelFormat(void *display, OSType pixelFormat) {
static void
setPixelFormat(void *display, OSType pixelFormat) {
static_cast<AVVideo *>(display).pixelFormat = pixelFormat;
}
};
std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t>
display(platf::mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
if (hwdevice_type != platf::mem_type_e::system) {
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
return nullptr;
@ -186,7 +193,8 @@ std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, const std::s
return display;
}
std::vector<std::string> display_names(mem_type_e hwdevice_type) {
std::vector<std::string>
display_names(mem_type_e hwdevice_type) {
__block std::vector<std::string> display_names;
auto display_array = [AVVideo displayNames];

View file

@ -36,7 +36,8 @@ struct KeyCodeMap {
};
// Customized less operator for using std::lower_bound() on a KeyCodeMap array.
bool operator<(const KeyCodeMap &a, const KeyCodeMap &b) {
bool
operator<(const KeyCodeMap &a, const KeyCodeMap &b) {
return a.win_keycode < b.win_keycode;
}
@ -212,7 +213,8 @@ const KeyCodeMap kKeyCodesMap[] = {
};
// clang-format on
int keysym(int keycode) {
int
keysym(int keycode) {
KeyCodeMap key_map;
key_map.win_keycode = keycode;
@ -227,7 +229,8 @@ int keysym(int keycode) {
return temp_map->mac_keycode;
}
void keyboard(input_t &input, uint16_t modcode, bool release) {
void
keyboard(input_t &input, uint16_t modcode, bool release) {
auto key = keysym(modcode);
BOOST_LOG(debug) << "got keycode: 0x"sv << std::hex << modcode << ", translated to: 0x" << std::hex << key << ", release:" << release;
@ -243,7 +246,6 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
key == kVK_Command || key == kVK_RightCommand ||
key == kVK_Option || key == kVK_RightOption ||
key == kVK_Control || key == kVK_RightControl) {
CGEventFlags mask;
switch (key) {
@ -277,29 +279,35 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
CGEventPost(kCGHIDEventTap, event);
}
void unicode(input_t &input, char *utf8, int size) {
void
unicode(input_t &input, char *utf8, int size) {
BOOST_LOG(info) << "unicode: Unicode input not yet implemented for MacOS."sv;
}
int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
int
alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
BOOST_LOG(info) << "alloc_gamepad: Gamepad not yet implemented for MacOS."sv;
return -1;
}
void free_gamepad(input_t &input, int nr) {
void
free_gamepad(input_t &input, int nr) {
BOOST_LOG(info) << "free_gamepad: Gamepad not yet implemented for MacOS."sv;
}
void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
void
gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
BOOST_LOG(info) << "gamepad: Gamepad not yet implemented for MacOS."sv;
}
// returns current mouse location:
inline CGPoint get_mouse_loc(input_t &input) {
inline CGPoint
get_mouse_loc(input_t &input) {
return CGEventGetLocation(((macos_input_t *) input.get())->mouse_event);
}
void post_mouse(input_t &input, CGMouseButton button, CGEventType type, CGPoint location, int click_count) {
void
post_mouse(input_t &input, CGMouseButton button, CGEventType type, CGPoint location, int click_count) {
BOOST_LOG(debug) << "mouse_event: "sv << button << ", type: "sv << type << ", location:"sv << location.x << ":"sv << location.y << " click_count: "sv << click_count;
auto macos_input = (macos_input_t *) input.get();
@ -328,7 +336,8 @@ void post_mouse(input_t &input, CGMouseButton button, CGEventType type, CGPoint
CGWarpMouseCursorPosition(location);
}
inline CGEventType event_type_mouse(input_t &input) {
inline CGEventType
event_type_mouse(input_t &input) {
auto macos_input = ((macos_input_t *) input.get());
if (macos_input->mouse_down[0]) {
@ -345,7 +354,8 @@ inline CGEventType event_type_mouse(input_t &input) {
}
}
void move_mouse(input_t &input, int deltaX, int deltaY) {
void
move_mouse(input_t &input, int deltaX, int deltaY) {
auto current = get_mouse_loc(input);
CGPoint location = CGPointMake(current.x + deltaX, current.y + deltaY);
@ -353,7 +363,8 @@ void move_mouse(input_t &input, int deltaX, int deltaY) {
post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, 0);
}
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
void
abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
auto scaling = ((macos_input_t *) input.get())->displayScaling;
CGPoint location = CGPointMake(x * scaling, y * scaling);
@ -361,7 +372,8 @@ void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y)
post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, 0);
}
uint64_t time_diff(uint64_t start) {
uint64_t
time_diff(uint64_t start) {
uint64_t elapsed;
Nanoseconds elapsedNano;
@ -371,7 +383,8 @@ uint64_t time_diff(uint64_t start) {
return *(uint64_t *) &elapsedNano;
}
void button_mouse(input_t &input, int button, bool release) {
void
button_mouse(input_t &input, int button, bool release) {
CGMouseButton mac_button;
CGEventType event;
@ -408,7 +421,8 @@ void button_mouse(input_t &input, int button, bool release) {
mouse->last_mouse_event[mac_button][release] = mach_absolute_time();
}
void scroll(input_t &input, int high_res_distance) {
void
scroll(input_t &input, int high_res_distance) {
CGEventRef upEvent = CGEventCreateScrollWheelEvent(
NULL,
kCGScrollEventUnitLine,
@ -417,11 +431,13 @@ void scroll(input_t &input, int high_res_distance) {
CFRelease(upEvent);
}
void hscroll(input_t &input, int high_res_distance) {
void
hscroll(input_t &input, int high_res_distance) {
// Unimplemented
}
input_t input() {
input_t
input() {
input_t result { new macos_input_t() };
auto macos_input = (macos_input_t *) result.get();
@ -455,7 +471,8 @@ input_t input() {
return result;
}
void freeInput(void *p) {
void
freeInput(void *p) {
auto *input = (macos_input_t *) p;
CFRelease(input->source);
@ -465,7 +482,8 @@ void freeInput(void *p) {
delete input;
}
std::vector<std::string_view> &supported_gamepads() {
std::vector<std::string_view> &
supported_gamepads() {
static std::vector<std::string_view> gamepads { ""sv };
return gamepads;

View file

@ -14,7 +14,8 @@ struct av_mic_t : public mic_t {
[av_audio_capture release];
}
capture_e sample(std::vector<std::int16_t> &sample_in) override {
capture_e
sample(std::vector<std::int16_t> &sample_in) override {
auto sample_size = sample_in.size();
uint32_t length = 0;
@ -40,12 +41,14 @@ struct macos_audio_control_t : public audio_control_t {
AVCaptureDevice *audio_capture_device;
public:
int set_sink(const std::string &sink) override {
int
set_sink(const std::string &sink) override {
BOOST_LOG(warning) << "audio_control_t::set_sink() unimplemented: "sv << sink;
return 0;
}
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
std::unique_ptr<mic_t>
microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
auto mic = std::make_unique<av_mic_t>();
const char *audio_sink = "";
@ -74,14 +77,16 @@ public:
return mic;
}
std::optional<sink_t> sink_info() override {
std::optional<sink_t>
sink_info() override {
sink_t sink;
return sink;
}
};
std::unique_ptr<audio_control_t> audio_control() {
std::unique_ptr<audio_control_t>
audio_control() {
return std::make_unique<macos_audio_control_t>();
}
} // namespace platf

View file

@ -8,8 +8,10 @@
namespace dyn {
typedef void (*apiproc)(void);
int load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict = true);
void *handle(const std::vector<const char *> &libs);
int
load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict = true);
void *
handle(const std::vector<const char *> &libs);
} // namespace dyn

View file

@ -23,11 +23,14 @@ namespace platf {
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 110000 // __MAC_11_0
// If they're not in the SDK then we can use our own function definitions.
// Need to use weak import so that this will link in macOS 10.14 and earlier
extern "C" bool CGPreflightScreenCaptureAccess(void) __attribute__((weak_import));
extern "C" bool CGRequestScreenCaptureAccess(void) __attribute__((weak_import));
extern "C" bool
CGPreflightScreenCaptureAccess(void) __attribute__((weak_import));
extern "C" bool
CGRequestScreenCaptureAccess(void) __attribute__((weak_import));
#endif
std::unique_ptr<deinit_t> init() {
std::unique_ptr<deinit_t>
init() {
// This will generate a warning about CGPreflightScreenCaptureAccess and
// CGRequestScreenCaptureAccess being unavailable before macOS 10.15, but
// we have a guard to prevent it from being called on those earlier systems.
@ -55,7 +58,8 @@ std::unique_ptr<deinit_t> init() {
return std::make_unique<deinit_t>();
}
fs::path appdata() {
fs::path
appdata() {
const char *homedir;
if ((homedir = getenv("HOME")) == nullptr) {
homedir = getpwuid(geteuid())->pw_dir;
@ -66,7 +70,8 @@ fs::path appdata() {
using ifaddr_t = util::safe_ptr<ifaddrs, freeifaddrs>;
ifaddr_t get_ifaddrs() {
ifaddr_t
get_ifaddrs() {
ifaddrs *p { nullptr };
getifaddrs(&p);
@ -74,7 +79,8 @@ ifaddr_t get_ifaddrs() {
return ifaddr_t { p };
}
std::string from_sockaddr(const sockaddr *const ip_addr) {
std::string
from_sockaddr(const sockaddr *const ip_addr) {
char data[INET6_ADDRSTRLEN];
auto family = ip_addr->sa_family;
@ -91,7 +97,8 @@ std::string from_sockaddr(const sockaddr *const ip_addr) {
return std::string { data };
}
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_addr) {
std::pair<std::uint16_t, std::string>
from_sockaddr_ex(const sockaddr *const ip_addr) {
char data[INET6_ADDRSTRLEN];
auto family = ip_addr->sa_family;
@ -111,7 +118,8 @@ std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_
return { port, std::string { data } };
}
std::string get_mac_address(const std::string_view &address) {
std::string
get_mac_address(const std::string_view &address) {
auto ifaddrs = get_ifaddrs();
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
@ -149,7 +157,8 @@ std::string get_mac_address(const std::string_view &address) {
return "00:00:00:00:00:00"s;
}
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
bp::child
run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
if (!group) {
if (!file) {
@ -169,34 +178,41 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
}
}
void adjust_thread_priority(thread_priority_e priority) {
void
adjust_thread_priority(thread_priority_e priority) {
// Unimplemented
}
void streaming_will_start() {
void
streaming_will_start() {
// Nothing to do
}
void streaming_will_stop() {
void
streaming_will_stop() {
// Nothing to do
}
bool restart_supported() {
bool
restart_supported() {
// Restart not supported yet
return false;
}
bool restart() {
bool
restart() {
// Restart not supported yet
return false;
}
bool send_batch(batched_send_info_t &send_info) {
bool
send_batch(batched_send_info_t &send_info) {
// Fall back to unbatched send calls
return false;
}
std::unique_ptr<deinit_t> enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
std::unique_ptr<deinit_t>
enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
// Unimplemented
//
// NB: When implementing, remember to consider that some routes can drop DSCP-tagged packets completely!
@ -206,7 +222,8 @@ std::unique_ptr<deinit_t> enable_socket_qos(uintptr_t native_socket, boost::asio
} // namespace platf
namespace dyn {
void *handle(const std::vector<const char *> &libs) {
void *
handle(const std::vector<const char *> &libs) {
void *handle;
for (auto lib : libs) {
@ -229,7 +246,8 @@ void *handle(const std::vector<const char *> &libs) {
return nullptr;
}
int load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict) {
int
load(void *handle, const std::vector<std::tuple<apiproc *, const char *>> &funcs, bool strict) {
int err = 0;
for (auto &func : funcs) {
TUPLE_2D_REF(fn, name, func);

View file

@ -9,13 +9,15 @@ extern "C" {
namespace platf {
void free_frame(AVFrame *frame) {
void
free_frame(AVFrame *frame) {
av_frame_free(&frame);
}
util::safe_ptr<AVFrame, free_frame> av_frame;
int nv12_zero_device::convert(platf::img_t &img) {
int
nv12_zero_device::convert(platf::img_t &img) {
av_frame_make_writable(av_frame.get());
av_img_t *av_img = (av_img_t *) &img;
@ -53,7 +55,8 @@ int nv12_zero_device::convert(platf::img_t &img) {
return result > 0 ? 0 : -1;
}
int nv12_zero_device::set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
int
nv12_zero_device::set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
this->frame = frame;
av_frame.reset(frame);
@ -63,10 +66,12 @@ int nv12_zero_device::set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
return 0;
}
void nv12_zero_device::set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {
void
nv12_zero_device::set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) {
}
int nv12_zero_device::init(void *display, resolution_fn_t resolution_fn, pixel_format_fn_t pixel_format_fn) {
int
nv12_zero_device::init(void *display, resolution_fn_t resolution_fn, pixel_format_fn_t pixel_format_fn) {
pixel_format_fn(display, '420v');
this->display = display;

View file

@ -17,11 +17,15 @@ public:
resolution_fn_t resolution_fn;
using pixel_format_fn_t = std::function<void(void *display, int pixelFormat)>;
int init(void *display, resolution_fn_t resolution_fn, pixel_format_fn_t pixel_format_fn);
int
init(void *display, resolution_fn_t resolution_fn, pixel_format_fn_t pixel_format_fn);
int convert(img_t &img);
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx);
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
int
convert(img_t &img);
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx);
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
};
} // namespace platf

View file

@ -195,8 +195,8 @@ simple_poll_quit_fn simple_poll_quit;
simple_poll_new_fn simple_poll_new;
simple_poll_free_fn simple_poll_free;
int init_common() {
int
init_common() {
static void *handle { nullptr };
static bool funcs_loaded = false;
@ -229,7 +229,8 @@ int init_common() {
return 0;
}
int init_client() {
int
init_client() {
if (init_common()) {
return -1;
}
@ -270,7 +271,8 @@ int init_client() {
namespace platf::publish {
template <class T>
void free(T *p) {
void
free(T *p) {
avahi::free(p);
}
@ -286,9 +288,11 @@ client_t client;
ptr_t<char> name;
void create_services(avahi::Client *c);
void
create_services(avahi::Client *c);
void entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, void *) {
void
entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, void *) {
group = g;
switch (state) {
@ -311,7 +315,8 @@ void entry_group_callback(avahi::EntryGroup *g, avahi::EntryGroupState state, vo
}
}
void create_services(avahi::Client *c) {
void
create_services(avahi::Client *c) {
int ret;
auto fg = util::fail_guard([]() {
@ -366,7 +371,8 @@ void create_services(avahi::Client *c) {
fg.disable();
}
void client_callback(avahi::Client *c, avahi::ClientState state, void *) {
void
client_callback(avahi::Client *c, avahi::ClientState state, void *) {
switch (state) {
case avahi::CLIENT_S_RUNNING:
create_services(c);
@ -388,7 +394,8 @@ class deinit_t : public ::platf::deinit_t {
public:
std::thread poll_thread;
deinit_t(std::thread poll_thread) : poll_thread { std::move(poll_thread) } {}
deinit_t(std::thread poll_thread):
poll_thread { std::move(poll_thread) } {}
~deinit_t() override {
if (avahi::simple_poll_quit && poll) {
@ -401,7 +408,8 @@ public:
}
};
[[nodiscard]] std::unique_ptr<::platf::deinit_t> start() {
[[nodiscard]] std::unique_ptr<::platf::deinit_t>
start() {
if (avahi::init_client()) {
return nullptr;
}

View file

@ -6,7 +6,6 @@
// http://eretik.omegahg.com/
// ----------------------------------------------------------------------------
#pragma once
#ifdef __MINGW32__
@ -39,11 +38,13 @@ class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient;
// ----------------------------------------------------------------------------
interface IPolicyConfig: public IUnknown {
public:
virtual HRESULT GetMixFormat(
virtual HRESULT
GetMixFormat(
PCWSTR,
WAVEFORMATEX **);
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
virtual HRESULT STDMETHODCALLTYPE
GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **);
@ -51,7 +52,8 @@ public:
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(
PCWSTR);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
virtual HRESULT STDMETHODCALLTYPE
SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *);
@ -66,25 +68,30 @@ public:
PCWSTR,
PINT64);
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
virtual HRESULT STDMETHODCALLTYPE
GetShareMode(
PCWSTR,
struct DeviceShareMode *);
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
virtual HRESULT STDMETHODCALLTYPE
SetShareMode(
PCWSTR,
struct DeviceShareMode *);
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
virtual HRESULT STDMETHODCALLTYPE
GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
virtual HRESULT STDMETHODCALLTYPE
SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
virtual HRESULT STDMETHODCALLTYPE
SetDefaultEndpoint(
PCWSTR wszDeviceId,
ERole eRole);
@ -110,16 +117,19 @@ class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") CPolicyConfigVistaCl
// ----------------------------------------------------------------------------
interface IPolicyConfigVista: public IUnknown {
public:
virtual HRESULT GetMixFormat(
virtual HRESULT
GetMixFormat(
PCWSTR,
WAVEFORMATEX **); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
virtual HRESULT STDMETHODCALLTYPE
GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
virtual HRESULT STDMETHODCALLTYPE
SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *);
@ -134,25 +144,30 @@ public:
PCWSTR,
PINT64); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
virtual HRESULT STDMETHODCALLTYPE
GetShareMode(
PCWSTR,
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
virtual HRESULT STDMETHODCALLTYPE
SetShareMode(
PCWSTR,
struct DeviceShareMode *); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
virtual HRESULT STDMETHODCALLTYPE
GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
virtual HRESULT STDMETHODCALLTYPE
SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
virtual HRESULT STDMETHODCALLTYPE
SetDefaultEndpoint(
PCWSTR wszDeviceId,
ERole eRole);

View file

@ -37,12 +37,14 @@ namespace platf::audio {
constexpr auto SAMPLE_RATE = 48000;
template <class T>
void Release(T *p) {
void
Release(T *p) {
p->Release();
}
template <class T>
void co_task_free(T *p) {
void
co_task_free(T *p) {
CoTaskMemFree((LPVOID) p);
}
@ -138,7 +140,8 @@ static format_t surround_51_side_speakers {
SPEAKER_SIDE_RIGHT,
};
WAVEFORMATEXTENSIBLE create_wave_format(const format_t &format) {
WAVEFORMATEXTENSIBLE
create_wave_format(const format_t &format) {
WAVEFORMATEXTENSIBLE wave_format;
wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
@ -156,7 +159,8 @@ WAVEFORMATEXTENSIBLE create_wave_format(const format_t &format) {
return wave_format;
}
int set_wave_format(audio::wave_format_t &wave_format, const format_t &format) {
int
set_wave_format(audio::wave_format_t &wave_format, const format_t &format) {
wave_format->nSamplesPerSec = SAMPLE_RATE;
wave_format->wBitsPerSample = 16;
@ -184,7 +188,8 @@ int set_wave_format(audio::wave_format_t &wave_format, const format_t &format) {
return 0;
}
audio_client_t make_audio_client(device_t &device, const format_t &format) {
audio_client_t
make_audio_client(device_t &device, const format_t &format) {
audio_client_t audio_client;
auto status = device->Activate(
IID_IAudioClient,
@ -216,11 +221,13 @@ audio_client_t make_audio_client(device_t &device, const format_t &format) {
return audio_client;
}
const wchar_t *no_null(const wchar_t *str) {
const wchar_t *
no_null(const wchar_t *str) {
return str ? str : L"Unknown";
}
bool validate_device(device_t &device) {
bool
validate_device(device_t &device) {
bool valid = false;
// Check for any valid format
@ -237,7 +244,8 @@ bool validate_device(device_t &device) {
return valid;
}
device_t default_device(device_enum_t &device_enum) {
device_t
default_device(device_enum_t &device_enum) {
device_t device;
HRESULT status;
status = device_enum->GetDefaultAudioEndpoint(
@ -245,7 +253,6 @@ device_t default_device(device_enum_t &device_enum) {
eConsole,
&device);
if (FAILED(status)) {
BOOST_LOG(error) << "Couldn't create audio Device [0x"sv << util::hex(status).to_string_view() << ']';
@ -257,7 +264,8 @@ device_t default_device(device_enum_t &device_enum) {
class mic_wasapi_t: public mic_t {
public:
capture_e sample(std::vector<std::int16_t> &sample_out) override {
capture_e
sample(std::vector<std::int16_t> &sample_out) override {
auto sample_size = sample_out.size();
// Refill the sample buffer if needed
@ -278,8 +286,8 @@ public:
return capture_e::ok;
}
int init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out) {
int
init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out) {
audio_event.reset(CreateEventA(nullptr, FALSE, FALSE, nullptr));
if (!audio_event) {
BOOST_LOG(error) << "Couldn't create Event handle"sv;
@ -375,7 +383,8 @@ public:
}
private:
capture_e _fill_buffer() {
capture_e
_fill_buffer() {
HRESULT status;
// Total number of samples
@ -465,7 +474,8 @@ public:
class audio_control_t: public ::platf::audio_control_t {
public:
std::optional<sink_t> sink_info() override {
std::optional<sink_t>
sink_info() override {
auto virtual_adapter_name = L"Steam Streaming Speakers"sv;
sink_t sink;
@ -553,7 +563,8 @@ public:
return sink;
}
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
std::unique_ptr<mic_t>
microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
auto mic = std::make_unique<mic_wasapi_t>();
if (mic->init(sample_rate, frame_size, channels)) {
@ -571,7 +582,8 @@ public:
* virtual-(format name)
* If it doesn't contain that prefix, then the format will not be changed
*/
std::optional<std::wstring> set_format(const std::string &sink) {
std::optional<std::wstring>
set_format(const std::string &sink) {
std::string_view sv { sink.c_str(), sink.size() };
format_t::type_e type = format_t::none;
@ -628,7 +640,8 @@ public:
return std::make_optional(std::move(wstring_device_id));
}
int set_sink(const std::string &sink) override {
int
set_sink(const std::string &sink) override {
auto wstring_device_id = set_format(sink);
if (!wstring_device_id) {
return -1;
@ -647,7 +660,8 @@ public:
return failure;
}
int init() {
int
init() {
auto status = CoCreateInstance(
CLSID_CPolicyConfigClient,
nullptr,
@ -674,10 +688,12 @@ namespace platf {
// It's not big enough to justify it's own source file :/
namespace dxgi {
int init();
int
init();
}
std::unique_ptr<audio_control_t> audio_control() {
std::unique_ptr<audio_control_t>
audio_control() {
auto control = std::make_unique<audio::audio_control_t>();
if (control->init()) {
@ -687,7 +703,8 @@ std::unique_ptr<audio_control_t> audio_control() {
return control;
}
std::unique_ptr<deinit_t> init() {
std::unique_ptr<deinit_t>
init() {
if (dxgi::init()) {
return nullptr;
}

View file

@ -23,7 +23,8 @@ extern const char *format_str[];
auto constexpr D3D11_CREATE_DEVICE_FLAGS = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
template <class T>
void Release(T *dxgi) {
void
Release(T *dxgi) {
dxgi->Release();
}
@ -78,15 +79,18 @@ struct cursor_t {
class gpu_cursor_t {
public:
gpu_cursor_t() : cursor_view { 0, 0, 0, 0, 0.0f, 1.0f } {};
void set_pos(LONG rel_x, LONG rel_y, bool visible) {
gpu_cursor_t():
cursor_view { 0, 0, 0, 0, 0.0f, 1.0f } {};
void
set_pos(LONG rel_x, LONG rel_y, bool visible) {
cursor_view.TopLeftX = rel_x;
cursor_view.TopLeftY = rel_y;
this->visible = visible;
}
void set_texture(LONG width, LONG height, texture2d_t &&texture) {
void
set_texture(LONG width, LONG height, texture2d_t &&texture) {
cursor_view.Width = width;
cursor_view.Height = height;
@ -107,17 +111,22 @@ public:
bool has_frame {};
bool use_dwmflush {};
capture_e next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p);
capture_e reset(dup_t::pointer dup_p = dup_t::pointer());
capture_e release_frame();
capture_e
next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p);
capture_e
reset(dup_t::pointer dup_p = dup_t::pointer());
capture_e
release_frame();
~duplication_t();
};
class display_base_t: public display_t {
public:
int init(const ::video::config_t &config, const std::string &display_name);
capture_e capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
int
init(const ::video::config_t &config, const std::string &display_name);
capture_e
capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<img_t> img, bool *cursor) override;
std::chrono::nanoseconds delay;
@ -142,34 +151,50 @@ public:
typedef NTSTATUS WINAPI (*PD3DKMTSetProcessSchedulingPriorityClass)(HANDLE, D3DKMT_SCHEDULINGPRIORITYCLASS);
virtual bool is_hdr() override;
virtual bool get_hdr_metadata(SS_HDR_METADATA &metadata) override;
virtual bool
is_hdr() override;
virtual bool
get_hdr_metadata(SS_HDR_METADATA &metadata) override;
protected:
int get_pixel_pitch() {
int
get_pixel_pitch() {
return (capture_format == DXGI_FORMAT_R16G16B16A16_FLOAT) ? 8 : 4;
}
const char *dxgi_format_to_string(DXGI_FORMAT format);
const char *colorspace_to_string(DXGI_COLOR_SPACE_TYPE type);
const char *
dxgi_format_to_string(DXGI_FORMAT format);
const char *
colorspace_to_string(DXGI_COLOR_SPACE_TYPE type);
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) = 0;
virtual int complete_img(img_t *img, bool dummy) = 0;
virtual std::vector<DXGI_FORMAT> get_supported_sdr_capture_formats() = 0;
virtual std::vector<DXGI_FORMAT> get_supported_hdr_capture_formats() = 0;
virtual capture_e
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) = 0;
virtual int
complete_img(img_t *img, bool dummy) = 0;
virtual std::vector<DXGI_FORMAT>
get_supported_sdr_capture_formats() = 0;
virtual std::vector<DXGI_FORMAT>
get_supported_hdr_capture_formats() = 0;
};
class display_ram_t: public display_base_t {
public:
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
virtual capture_e
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
std::shared_ptr<img_t> alloc_img() override;
int dummy_img(img_t *img) override;
int complete_img(img_t *img, bool dummy) override;
std::vector<DXGI_FORMAT> get_supported_sdr_capture_formats() override;
std::vector<DXGI_FORMAT> get_supported_hdr_capture_formats() override;
std::shared_ptr<img_t>
alloc_img() override;
int
dummy_img(img_t *img) override;
int
complete_img(img_t *img, bool dummy) override;
std::vector<DXGI_FORMAT>
get_supported_sdr_capture_formats() override;
std::vector<DXGI_FORMAT>
get_supported_hdr_capture_formats() override;
int init(const ::video::config_t &config, const std::string &display_name);
int
init(const ::video::config_t &config, const std::string &display_name);
cursor_t cursor;
D3D11_MAPPED_SUBRESOURCE img_info;
@ -178,17 +203,25 @@ public:
class display_vram_t: public display_base_t, public std::enable_shared_from_this<display_vram_t> {
public:
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
virtual capture_e
snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor_visible) override;
std::shared_ptr<img_t> alloc_img() override;
int dummy_img(img_t *img_base) override;
int complete_img(img_t *img_base, bool dummy) override;
std::vector<DXGI_FORMAT> get_supported_sdr_capture_formats() override;
std::vector<DXGI_FORMAT> get_supported_hdr_capture_formats() override;
std::shared_ptr<img_t>
alloc_img() override;
int
dummy_img(img_t *img_base) override;
int
complete_img(img_t *img_base, bool dummy) override;
std::vector<DXGI_FORMAT>
get_supported_sdr_capture_formats() override;
std::vector<DXGI_FORMAT>
get_supported_hdr_capture_formats() override;
int init(const ::video::config_t &config, const std::string &display_name);
int
init(const ::video::config_t &config, const std::string &display_name);
std::shared_ptr<platf::hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override;
std::shared_ptr<platf::hwdevice_t>
make_hwdevice(pix_fmt_e pix_fmt) override;
sampler_state_t sampler_linear;

View file

@ -25,7 +25,8 @@ using namespace std::literals;
namespace platf::dxgi {
namespace bp = boost::process;
capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p) {
capture_e
duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p) {
auto capture_status = release_frame();
if (capture_status != capture_e::ok) {
return capture_status;
@ -53,7 +54,8 @@ capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::ch
}
}
capture_e duplication_t::reset(dup_t::pointer dup_p) {
capture_e
duplication_t::reset(dup_t::pointer dup_p) {
auto capture_status = release_frame();
dup.reset(dup_p);
@ -61,7 +63,8 @@ capture_e duplication_t::reset(dup_t::pointer dup_p) {
return capture_status;
}
capture_e duplication_t::release_frame() {
capture_e
duplication_t::release_frame() {
if (!has_frame) {
return capture_e::ok;
}
@ -88,7 +91,8 @@ duplication_t::~duplication_t() {
release_frame();
}
capture_e display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
capture_e
display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
auto next_frame = std::chrono::steady_clock::now();
// Use CREATE_WAITABLE_TIMER_HIGH_RESOLUTION if supported (Windows 10 1809+)
@ -151,7 +155,8 @@ capture_e display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<:
return capture_e::ok;
}
bool set_gpu_preference_on_self(int preference) {
bool
set_gpu_preference_on_self(int preference) {
// The GPU preferences key uses app path as the value name.
WCHAR sunshine_path[MAX_PATH];
GetModuleFileNameW(NULL, sunshine_path, ARRAYSIZE(sunshine_path));
@ -184,7 +189,8 @@ bool set_gpu_preference_on_self(int preference) {
// (even if you try sneaky stuff like passing the ID3D11Device for the iGPU and the
// virtual DXGIOutput from the dGPU). Because the GPU preference is once-per-process,
// we spawn a helper tool to probe for us before we set our own GPU preference.
bool probe_for_gpu_preference(const std::string &display_name) {
bool
probe_for_gpu_preference(const std::string &display_name) {
// If we've already been through here, there's nothing to do this time.
static bool set_gpu_preference = false;
if (set_gpu_preference) {
@ -235,7 +241,8 @@ bool probe_for_gpu_preference(const std::string &display_name) {
return false;
}
bool test_dxgi_duplication(adapter_t &adapter, output_t &output) {
bool
test_dxgi_duplication(adapter_t &adapter, output_t &output) {
D3D_FEATURE_LEVEL featureLevels[] {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
@ -283,7 +290,8 @@ bool test_dxgi_duplication(adapter_t &adapter, output_t &output) {
return false;
}
int display_base_t::init(const ::video::config_t &config, const std::string &display_name) {
int
display_base_t::init(const ::video::config_t &config, const std::string &display_name) {
std::once_flag windows_cpp_once_flag;
std::call_once(windows_cpp_once_flag, []() {
@ -588,7 +596,8 @@ int display_base_t::init(const ::video::config_t &config, const std::string &dis
return 0;
}
bool display_base_t::is_hdr() {
bool
display_base_t::is_hdr() {
dxgi::output6_t output6 {};
auto status = output->QueryInterface(IID_IDXGIOutput6, (void **) &output6);
@ -603,7 +612,8 @@ bool display_base_t::is_hdr() {
return desc1.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
}
bool display_base_t::get_hdr_metadata(SS_HDR_METADATA &metadata) {
bool
display_base_t::get_hdr_metadata(SS_HDR_METADATA &metadata) {
dxgi::output6_t output6 {};
std::memset(&metadata, 0, sizeof(metadata));
@ -781,11 +791,13 @@ const char *format_str[] = {
"DXGI_FORMAT_V408"
};
const char *display_base_t::dxgi_format_to_string(DXGI_FORMAT format) {
const char *
display_base_t::dxgi_format_to_string(DXGI_FORMAT format) {
return format_str[format];
}
const char *display_base_t::colorspace_to_string(DXGI_COLOR_SPACE_TYPE type) {
const char *
display_base_t::colorspace_to_string(DXGI_COLOR_SPACE_TYPE type) {
const char *type_str[] = {
"DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709",
"DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709",
@ -825,7 +837,8 @@ const char *display_base_t::colorspace_to_string(DXGI_COLOR_SPACE_TYPE type) {
} // namespace platf::dxgi
namespace platf {
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t>
display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
if (hwdevice_type == mem_type_e::dxgi) {
auto disp = std::make_shared<dxgi::display_vram_t>();
@ -844,7 +857,8 @@ std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &
return nullptr;
}
std::vector<std::string> display_names(mem_type_e) {
std::vector<std::string>
display_names(mem_type_e) {
std::vector<std::string> display_names;
HRESULT status;

View file

@ -13,7 +13,8 @@ struct img_t : public ::platf::img_t {
}
};
void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
void
blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
int height = cursor.shape_info.Height / 2;
int width = cursor.shape_info.Width;
int pitch = cursor.shape_info.Pitch;
@ -75,7 +76,8 @@ void blend_cursor_monochrome(const cursor_t &cursor, img_t &img) {
}
}
void apply_color_alpha(int *img_pixel_p, int cursor_pixel) {
void
apply_color_alpha(int *img_pixel_p, int cursor_pixel) {
auto colors_out = (std::uint8_t *) &cursor_pixel;
auto colors_in = (std::uint8_t *) img_pixel_p;
@ -91,7 +93,8 @@ void apply_color_alpha(int *img_pixel_p, int cursor_pixel) {
}
}
void apply_color_masked(int *img_pixel_p, int cursor_pixel) {
void
apply_color_masked(int *img_pixel_p, int cursor_pixel) {
//TODO: When use of IDXGIOutput5 is implemented, support different color formats
auto alpha = ((std::uint8_t *) &cursor_pixel)[3];
if (alpha == 0xFF) {
@ -102,7 +105,8 @@ void apply_color_masked(int *img_pixel_p, int cursor_pixel) {
}
}
void blend_cursor_color(const cursor_t &cursor, img_t &img, const bool masked) {
void
blend_cursor_color(const cursor_t &cursor, img_t &img, const bool masked) {
int height = cursor.shape_info.Height;
int width = cursor.shape_info.Width;
int pitch = cursor.shape_info.Pitch;
@ -149,7 +153,8 @@ void blend_cursor_color(const cursor_t &cursor, img_t &img, const bool masked) {
}
}
void blend_cursor(const cursor_t &cursor, img_t &img) {
void
blend_cursor(const cursor_t &cursor, img_t &img) {
switch (cursor.shape_info.Type) {
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
blend_cursor_color(cursor, img, false);
@ -165,7 +170,8 @@ void blend_cursor(const cursor_t &cursor, img_t &img) {
}
}
capture_e display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
capture_e
display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
auto img = (img_t *) img_base;
HRESULT status;
@ -301,7 +307,8 @@ capture_e display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::millise
return capture_e::ok;
}
std::shared_ptr<platf::img_t> display_ram_t::alloc_img() {
std::shared_ptr<platf::img_t>
display_ram_t::alloc_img() {
auto img = std::make_shared<img_t>();
// Initialize fields that are format-independent
@ -311,7 +318,8 @@ std::shared_ptr<platf::img_t> display_ram_t::alloc_img() {
return img;
}
int display_ram_t::complete_img(platf::img_t *img, bool dummy) {
int
display_ram_t::complete_img(platf::img_t *img, bool dummy) {
// If this is not a dummy image, we must know the format by now
if (!dummy && capture_format == DXGI_FORMAT_UNKNOWN) {
BOOST_LOG(error) << "display_ram_t::complete_img() called with unknown capture format!";
@ -339,7 +347,8 @@ int display_ram_t::complete_img(platf::img_t *img, bool dummy) {
return 0;
}
int display_ram_t::dummy_img(platf::img_t *img) {
int
display_ram_t::dummy_img(platf::img_t *img) {
if (complete_img(img, true)) {
return -1;
}
@ -348,16 +357,19 @@ int display_ram_t::dummy_img(platf::img_t *img) {
return 0;
}
std::vector<DXGI_FORMAT> display_ram_t::get_supported_sdr_capture_formats() {
std::vector<DXGI_FORMAT>
display_ram_t::get_supported_sdr_capture_formats() {
return { DXGI_FORMAT_B8G8R8A8_UNORM };
}
std::vector<DXGI_FORMAT> display_ram_t::get_supported_hdr_capture_formats() {
std::vector<DXGI_FORMAT>
display_ram_t::get_supported_hdr_capture_formats() {
// HDR is unsupported
return {};
}
int display_ram_t::init(const ::video::config_t &config, const std::string &display_name) {
int
display_ram_t::init(const ::video::config_t &config, const std::string &display_name) {
if (display_base_t::init(config, display_name)) {
return -1;
}

View file

@ -14,13 +14,13 @@ extern "C" {
#include "src/main.h"
#include "src/video.h"
#define SUNSHINE_SHADERS_DIR SUNSHINE_ASSETS_DIR "/shaders/directx"
namespace platf {
using namespace std::literals;
}
static void free_frame(AVFrame *frame) {
static void
free_frame(AVFrame *frame) {
av_frame_free(&frame);
}
@ -29,7 +29,8 @@ using frame_t = util::safe_ptr<AVFrame, free_frame>;
namespace platf::dxgi {
template <class T>
buf_t make_buffer(device_t::pointer device, const T &t) {
buf_t
make_buffer(device_t::pointer device, const T &t) {
static_assert(sizeof(T) % 16 == 0, "Buffer needs to be aligned on a 16-byte alignment");
D3D11_BUFFER_DESC buffer_desc {
@ -52,7 +53,8 @@ buf_t make_buffer(device_t::pointer device, const T &t) {
return buf_t { buf_p };
}
blend_t make_blend(device_t::pointer device, bool enable, bool invert) {
blend_t
make_blend(device_t::pointer device, bool enable, bool invert) {
D3D11_BLEND_DESC bdesc {};
auto &rt = bdesc.RenderTarget[0];
rt.BlendEnable = enable;
@ -121,7 +123,8 @@ struct img_d3d_t : public platf::img_t {
};
};
util::buffer_t<std::uint8_t> make_cursor_xor_image(const util::buffer_t<std::uint8_t> &img_data, DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info) {
util::buffer_t<std::uint8_t>
make_cursor_xor_image(const util::buffer_t<std::uint8_t> &img_data, DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info) {
constexpr std::uint32_t inverted = 0xFFFFFFFF;
constexpr std::uint32_t transparent = 0;
@ -191,7 +194,8 @@ util::buffer_t<std::uint8_t> make_cursor_xor_image(const util::buffer_t<std::uin
return cursor_img;
}
util::buffer_t<std::uint8_t> make_cursor_alpha_image(const util::buffer_t<std::uint8_t> &img_data, DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info) {
util::buffer_t<std::uint8_t>
make_cursor_alpha_image(const util::buffer_t<std::uint8_t> &img_data, DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info) {
constexpr std::uint32_t black = 0xFF000000;
constexpr std::uint32_t white = 0xFFFFFFFF;
constexpr std::uint32_t transparent = 0;
@ -265,7 +269,8 @@ util::buffer_t<std::uint8_t> make_cursor_alpha_image(const util::buffer_t<std::u
return cursor_img;
}
blob_t compile_shader(LPCSTR file, LPCSTR entrypoint, LPCSTR shader_model) {
blob_t
compile_shader(LPCSTR file, LPCSTR entrypoint, LPCSTR shader_model) {
blob_t::pointer msg_p = nullptr;
blob_t::pointer compiled_p;
@ -292,17 +297,20 @@ blob_t compile_shader(LPCSTR file, LPCSTR entrypoint, LPCSTR shader_model) {
return blob_t { compiled_p };
}
blob_t compile_pixel_shader(LPCSTR file) {
blob_t
compile_pixel_shader(LPCSTR file) {
return compile_shader(file, "main_ps", "ps_5_0");
}
blob_t compile_vertex_shader(LPCSTR file) {
blob_t
compile_vertex_shader(LPCSTR file) {
return compile_shader(file, "main_vs", "vs_5_0");
}
class hwdevice_t: public platf::hwdevice_t {
public:
int convert(platf::img_t &img_base) override {
int
convert(platf::img_t &img_base) override {
auto &img = (img_d3d_t &) img_base;
auto &img_ctx = img_ctx_map[img.id];
@ -341,7 +349,8 @@ public:
return 0;
}
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
switch (colorspace) {
case 5: // SWS_CS_SMPTE170M
color_p = &::video::colors[0];
@ -373,7 +382,8 @@ public:
this->color_matrix = std::move(color_matrix);
}
void init_hwframes(AVHWFramesContext *frames) override {
void
init_hwframes(AVHWFramesContext *frames) override {
// We may be called with a QSV or D3D11VA context
if (frames->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
auto d3d11_frames = (AVD3D11VAFramesContext *) frames->hwctx;
@ -387,7 +397,8 @@ public:
frames->initial_pool_size = 1;
}
int prepare_to_derive_context(int hw_device_type) override {
int
prepare_to_derive_context(int hw_device_type) override {
// QuickSync requires our device to be multithread-protected
if (hw_device_type == AV_HWDEVICE_TYPE_QSV) {
multithread_t mt;
@ -404,7 +415,8 @@ public:
return 0;
}
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) override {
this->hwframe.reset(frame);
this->frame = frame;
@ -498,10 +510,10 @@ public:
return 0;
}
int init(
int
init(
std::shared_ptr<platf::display_t> display, adapter_t::pointer adapter_p,
pix_fmt_e pix_fmt) {
D3D_FEATURE_LEVEL featureLevels[] {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
@ -642,7 +654,8 @@ private:
shader_res_t encoder_input_res;
keyed_mutex_t encoder_mutex;
void reset() {
void
reset() {
capture_texture_p = nullptr;
encoder_texture.reset();
encoder_input_res.reset();
@ -650,7 +663,8 @@ private:
}
};
int initialize_image_context(const img_d3d_t &img, encoder_img_ctx_t &img_ctx) {
int
initialize_image_context(const img_d3d_t &img, encoder_img_ctx_t &img_ctx) {
// If we've already opened the shared texture, we're done
if (img_ctx.encoder_texture && img.capture_texture.get() == img_ctx.capture_texture_p) {
return 0;
@ -733,7 +747,8 @@ public:
device_ctx_t device_ctx;
};
bool set_cursor_texture(device_t::pointer device, gpu_cursor_t &cursor, util::buffer_t<std::uint8_t> &&cursor_img, DXGI_OUTDUPL_POINTER_SHAPE_INFO &shape_info) {
bool
set_cursor_texture(device_t::pointer device, gpu_cursor_t &cursor, util::buffer_t<std::uint8_t> &&cursor_img, DXGI_OUTDUPL_POINTER_SHAPE_INFO &shape_info) {
// This cursor image may not be used
if (cursor_img.size() == 0) {
cursor.input_res.reset();
@ -777,7 +792,8 @@ bool set_cursor_texture(device_t::pointer device, gpu_cursor_t &cursor, util::bu
return true;
}
capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
capture_e
display_vram_t::snapshot(platf::img_t *img_base, std::chrono::milliseconds timeout, bool cursor_visible) {
auto img = (img_d3d_t *) img_base;
HRESULT status;
@ -965,7 +981,8 @@ capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::millisec
return capture_e::ok;
}
int display_vram_t::init(const ::video::config_t &config, const std::string &display_name) {
int
display_vram_t::init(const ::video::config_t &config, const std::string &display_name) {
if (display_base_t::init(config, display_name)) {
return -1;
}
@ -1034,7 +1051,8 @@ int display_vram_t::init(const ::video::config_t &config, const std::string &dis
return 0;
}
std::shared_ptr<platf::img_t> display_vram_t::alloc_img() {
std::shared_ptr<platf::img_t>
display_vram_t::alloc_img() {
auto img = std::make_shared<img_d3d_t>();
// Initialize format-independent fields
@ -1047,7 +1065,8 @@ std::shared_ptr<platf::img_t> display_vram_t::alloc_img() {
}
// This cannot use ID3D11DeviceContext because it can be called concurrently by the encoding thread
int display_vram_t::complete_img(platf::img_t *img_base, bool dummy) {
int
display_vram_t::complete_img(platf::img_t *img_base, bool dummy) {
auto img = (img_d3d_t *) img_base;
// If this already has a capture texture and it's not switching dummy state, nothing to do
@ -1134,15 +1153,18 @@ int display_vram_t::complete_img(platf::img_t *img_base, bool dummy) {
}
// This cannot use ID3D11DeviceContext because it can be called concurrently by the encoding thread
int display_vram_t::dummy_img(platf::img_t *img_base) {
int
display_vram_t::dummy_img(platf::img_t *img_base) {
return complete_img(img_base, true);
}
std::vector<DXGI_FORMAT> display_vram_t::get_supported_sdr_capture_formats() {
std::vector<DXGI_FORMAT>
display_vram_t::get_supported_sdr_capture_formats() {
return { DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM };
}
std::vector<DXGI_FORMAT> display_vram_t::get_supported_hdr_capture_formats() {
std::vector<DXGI_FORMAT>
display_vram_t::get_supported_hdr_capture_formats() {
return {
// scRGB FP16 is the desired format for HDR content. This will also handle
// 10-bit SDR displays with the increased precision of FP16 vs 8-bit UNORMs.
@ -1164,7 +1186,8 @@ std::vector<DXGI_FORMAT> display_vram_t::get_supported_hdr_capture_formats() {
};
}
std::shared_ptr<platf::hwdevice_t> display_vram_t::make_hwdevice(pix_fmt_e pix_fmt) {
std::shared_ptr<platf::hwdevice_t>
display_vram_t::make_hwdevice(pix_fmt_e pix_fmt) {
if (pix_fmt != platf::pix_fmt_e::nv12 && pix_fmt != platf::pix_fmt_e::p010) {
BOOST_LOG(error) << "display_vram_t doesn't support pixel format ["sv << from_pix_fmt(pix_fmt) << ']';
@ -1185,7 +1208,8 @@ std::shared_ptr<platf::hwdevice_t> display_vram_t::make_hwdevice(pix_fmt_e pix_f
return hwdevice;
}
int init() {
int
init() {
BOOST_LOG(info) << "Compiling shaders..."sv;
scene_vs_hlsl = compile_vertex_shader(SUNSHINE_SHADERS_DIR "/SceneVS.hlsl");
if (!scene_vs_hlsl) {

View file

@ -22,7 +22,8 @@ constexpr touch_port_t target_touch_port {
using client_t = util::safe_ptr<_VIGEM_CLIENT_T, vigem_free>;
using target_t = util::safe_ptr<_VIGEM_TARGET_T, vigem_target_free>;
static VIGEM_TARGET_TYPE map(const std::string_view &gp) {
static VIGEM_TARGET_TYPE
map(const std::string_view &gp) {
if (gp == "x360"sv) {
return Xbox360Wired;
}
@ -30,14 +31,16 @@ static VIGEM_TARGET_TYPE map(const std::string_view &gp) {
return DualShock4Wired;
}
void CALLBACK x360_notify(
void CALLBACK
x360_notify(
client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor, std::uint8_t smallMotor,
std::uint8_t /* led_number */,
void *userdata);
void CALLBACK ds4_notify(
void CALLBACK
ds4_notify(
client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor, std::uint8_t smallMotor,
@ -46,7 +49,8 @@ void CALLBACK ds4_notify(
class vigem_t {
public:
int init() {
int
init() {
VIGEM_ERROR status;
client.reset(vigem_alloc());
@ -63,7 +67,8 @@ public:
return 0;
}
int alloc_gamepad_interal(int nr, rumble_queue_t &rumble_queue, VIGEM_TARGET_TYPE gp_type) {
int
alloc_gamepad_interal(int nr, rumble_queue_t &rumble_queue, VIGEM_TARGET_TYPE gp_type) {
auto &[rumble, gp] = gamepads[nr];
assert(!gp);
@ -97,7 +102,8 @@ public:
return 0;
}
void free_target(int nr) {
void
free_target(int nr) {
auto &[_, gp] = gamepads[nr];
if (gp && vigem_target_is_attached(gp.get())) {
@ -110,7 +116,8 @@ public:
gp.reset();
}
void rumble(target_t::pointer target, std::uint8_t smallMotor, std::uint8_t largeMotor) {
void
rumble(target_t::pointer target, std::uint8_t smallMotor, std::uint8_t largeMotor) {
for (int x = 0; x < gamepads.size(); ++x) {
auto &[rumble_queue, gp] = gamepads[x];
@ -142,13 +149,13 @@ public:
client_t client;
};
void CALLBACK x360_notify(
void CALLBACK
x360_notify(
client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor, std::uint8_t smallMotor,
std::uint8_t /* led_number */,
void *userdata) {
BOOST_LOG(debug)
<< "largeMotor: "sv << (int) largeMotor << std::endl
<< "smallMotor: "sv << (int) smallMotor;
@ -156,13 +163,13 @@ void CALLBACK x360_notify(
task_pool.push(&vigem_t::rumble, (vigem_t *) userdata, target, smallMotor, largeMotor);
}
void CALLBACK ds4_notify(
void CALLBACK
ds4_notify(
client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor, std::uint8_t smallMotor,
DS4_LIGHTBAR_COLOR /* led_color */,
void *userdata) {
BOOST_LOG(debug)
<< "largeMotor: "sv << (int) largeMotor << std::endl
<< "smallMotor: "sv << (int) smallMotor;
@ -180,7 +187,8 @@ struct input_raw_t {
HKL active_layout;
};
input_t input() {
input_t
input() {
input_t result { new input_raw_t {} };
auto &raw = *(input_raw_t *) result.get();
@ -208,7 +216,8 @@ input_t input() {
return result;
}
void send_input(INPUT &i) {
void
send_input(INPUT &i) {
retry:
auto send = SendInput(1, &i, sizeof(INPUT));
if (send != 1) {
@ -221,7 +230,8 @@ retry:
}
}
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
void
abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
INPUT i {};
i.type = INPUT_MOUSE;
@ -243,7 +253,8 @@ void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y)
send_input(i);
}
void move_mouse(input_t &input, int deltaX, int deltaY) {
void
move_mouse(input_t &input, int deltaX, int deltaY) {
INPUT i {};
i.type = INPUT_MOUSE;
@ -256,7 +267,8 @@ void move_mouse(input_t &input, int deltaX, int deltaY) {
send_input(i);
}
void button_mouse(input_t &input, int button, bool release) {
void
button_mouse(input_t &input, int button, bool release) {
constexpr auto KEY_STATE_DOWN = (SHORT) 0x8000;
INPUT i {};
@ -299,7 +311,8 @@ void button_mouse(input_t &input, int button, bool release) {
send_input(i);
}
void scroll(input_t &input, int distance) {
void
scroll(input_t &input, int distance) {
INPUT i {};
i.type = INPUT_MOUSE;
@ -311,7 +324,8 @@ void scroll(input_t &input, int distance) {
send_input(i);
}
void hscroll(input_t &input, int distance) {
void
hscroll(input_t &input, int distance) {
INPUT i {};
i.type = INPUT_MOUSE;
@ -323,7 +337,8 @@ void hscroll(input_t &input, int distance) {
send_input(i);
}
void keyboard(input_t &input, uint16_t modcode, bool release) {
void
keyboard(input_t &input, uint16_t modcode, bool release) {
auto raw = (input_raw_t *) input.get();
INPUT i {};
@ -372,7 +387,8 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
send_input(i);
}
void unicode(input_t &input, char *utf8, int size) {
void
unicode(input_t &input, char *utf8, int size) {
// We can do no worse than one UTF-16 character per byte of UTF-8
WCHAR wide[size];
@ -400,7 +416,8 @@ void unicode(input_t &input, char *utf8, int size) {
}
}
int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
int
alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
auto raw = (input_raw_t *) input.get();
if (!raw->vigem) {
@ -410,7 +427,8 @@ int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {
return raw->vigem->alloc_gamepad_interal(nr, rumble_queue, map(config::input.gamepad));
}
void free_gamepad(input_t &input, int nr) {
void
free_gamepad(input_t &input, int nr) {
auto raw = (input_raw_t *) input.get();
if (!raw->vigem) {
@ -420,13 +438,15 @@ void free_gamepad(input_t &input, int nr) {
raw->vigem->free_target(nr);
}
static VIGEM_ERROR x360_update(client_t::pointer client, target_t::pointer gp, const gamepad_state_t &gamepad_state) {
static VIGEM_ERROR
x360_update(client_t::pointer client, target_t::pointer gp, const gamepad_state_t &gamepad_state) {
auto &xusb = *(PXUSB_REPORT) &gamepad_state;
return vigem_target_x360_update(client, gp, xusb);
}
static DS4_DPAD_DIRECTIONS ds4_dpad(const gamepad_state_t &gamepad_state) {
static DS4_DPAD_DIRECTIONS
ds4_dpad(const gamepad_state_t &gamepad_state) {
auto flags = gamepad_state.buttonFlags;
if (flags & DPAD_UP) {
if (flags & DPAD_RIGHT) {
@ -463,7 +483,8 @@ static DS4_DPAD_DIRECTIONS ds4_dpad(const gamepad_state_t &gamepad_state) {
return DS4_BUTTON_DPAD_NONE;
}
static DS4_BUTTONS ds4_buttons(const gamepad_state_t &gamepad_state) {
static DS4_BUTTONS
ds4_buttons(const gamepad_state_t &gamepad_state) {
int buttons {};
auto flags = gamepad_state.buttonFlags;
@ -485,7 +506,8 @@ static DS4_BUTTONS ds4_buttons(const gamepad_state_t &gamepad_state) {
return (DS4_BUTTONS) buttons;
}
static DS4_SPECIAL_BUTTONS ds4_special_buttons(const gamepad_state_t &gamepad_state) {
static DS4_SPECIAL_BUTTONS
ds4_special_buttons(const gamepad_state_t &gamepad_state) {
int buttons {};
if (gamepad_state.buttonFlags & BACK) buttons |= DS4_SPECIAL_BUTTON_TOUCHPAD;
@ -494,17 +516,20 @@ static DS4_SPECIAL_BUTTONS ds4_special_buttons(const gamepad_state_t &gamepad_st
return (DS4_SPECIAL_BUTTONS) buttons;
}
static std::uint8_t to_ds4_triggerX(std::int16_t v) {
static std::uint8_t
to_ds4_triggerX(std::int16_t v) {
return (v + std::numeric_limits<std::uint16_t>::max() / 2 + 1) / 257;
}
static std::uint8_t to_ds4_triggerY(std::int16_t v) {
static std::uint8_t
to_ds4_triggerY(std::int16_t v) {
auto new_v = -((std::numeric_limits<std::uint16_t>::max() / 2 + v - 1)) / 257;
return new_v == 0 ? 0xFF : (std::uint8_t) new_v;
}
static VIGEM_ERROR ds4_update(client_t::pointer client, target_t::pointer gp, const gamepad_state_t &gamepad_state) {
static VIGEM_ERROR
ds4_update(client_t::pointer client, target_t::pointer gp, const gamepad_state_t &gamepad_state) {
DS4_REPORT report;
DS4_REPORT_INIT(&report);
@ -524,8 +549,8 @@ static VIGEM_ERROR ds4_update(client_t::pointer client, target_t::pointer gp, co
return vigem_target_ds4_update(client, gp, report);
}
void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
void
gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
auto vigem = ((input_raw_t *) input.get())->vigem;
// If there is no gamepad support
@ -549,13 +574,15 @@ void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
}
}
void freeInput(void *p) {
void
freeInput(void *p) {
auto input = (input_raw_t *) p;
delete input;
}
std::vector<std::string_view> &supported_gamepads() {
std::vector<std::string_view> &
supported_gamepads() {
// ds4 == ps4
static std::vector<std::string_view> gps {
"x360"sv, "ds4"sv, "ps4"sv

View file

@ -63,13 +63,15 @@ decltype(WlanFreeMemory) *fn_WlanFreeMemory = nullptr;
decltype(WlanEnumInterfaces) *fn_WlanEnumInterfaces = nullptr;
decltype(WlanSetInterface) *fn_WlanSetInterface = nullptr;
std::filesystem::path appdata() {
std::filesystem::path
appdata() {
WCHAR sunshine_path[MAX_PATH];
GetModuleFileNameW(NULL, sunshine_path, _countof(sunshine_path));
return std::filesystem::path { sunshine_path }.remove_filename() / L"config"sv;
}
std::string from_sockaddr(const sockaddr *const socket_address) {
std::string
from_sockaddr(const sockaddr *const socket_address) {
char data[INET6_ADDRSTRLEN];
auto family = socket_address->sa_family;
@ -84,7 +86,8 @@ std::string from_sockaddr(const sockaddr *const socket_address) {
return std::string { data };
}
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_addr) {
std::pair<std::uint16_t, std::string>
from_sockaddr_ex(const sockaddr *const ip_addr) {
char data[INET6_ADDRSTRLEN];
auto family = ip_addr->sa_family;
@ -102,7 +105,8 @@ std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const ip_
return { port, std::string { data } };
}
adapteraddrs_t get_adapteraddrs() {
adapteraddrs_t
get_adapteraddrs() {
adapteraddrs_t info { nullptr };
ULONG size = 0;
@ -113,7 +117,8 @@ adapteraddrs_t get_adapteraddrs() {
return info;
}
std::string get_mac_address(const std::string_view &address) {
std::string
get_mac_address(const std::string_view &address) {
adapteraddrs_t info = get_adapteraddrs();
for (auto adapter_pos = info.get(); adapter_pos != nullptr; adapter_pos = adapter_pos->Next) {
for (auto addr_pos = adapter_pos->FirstUnicastAddress; addr_pos != nullptr; addr_pos = addr_pos->Next) {
@ -134,7 +139,8 @@ std::string get_mac_address(const std::string_view &address) {
return "00:00:00:00:00:00"s;
}
HDESK syncThreadDesktop() {
HDESK
syncThreadDesktop() {
auto hDesk = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, FALSE, GENERIC_ALL);
if (!hDesk) {
auto err = GetLastError();
@ -153,7 +159,8 @@ HDESK syncThreadDesktop() {
return hDesk;
}
void print_status(const std::string_view &prefix, HRESULT status) {
void
print_status(const std::string_view &prefix, HRESULT status) {
char err_string[1024];
DWORD bytes = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
@ -167,7 +174,8 @@ void print_status(const std::string_view &prefix, HRESULT status) {
BOOST_LOG(error) << prefix << ": "sv << std::string_view { err_string, bytes };
}
std::wstring utf8_to_wide_string(const std::string &str) {
std::wstring
utf8_to_wide_string(const std::string &str) {
// Determine the size required for the destination string
int chars = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.length(), NULL, 0);
@ -179,7 +187,8 @@ std::wstring utf8_to_wide_string(const std::string &str) {
return std::wstring(buffer, chars);
}
std::string wide_to_utf8_string(const std::wstring &str) {
std::string
wide_to_utf8_string(const std::wstring &str) {
// Determine the size required for the destination string
int bytes = WideCharToMultiByte(CP_UTF8, 0, str.data(), str.length(), NULL, 0, NULL, NULL);
@ -191,7 +200,8 @@ std::string wide_to_utf8_string(const std::wstring &str) {
return std::string(buffer, bytes);
}
HANDLE duplicate_shell_token() {
HANDLE
duplicate_shell_token() {
// Get the shell window (will usually be owned by explorer.exe)
HWND shell_window = GetShellWindow();
if (!shell_window) {
@ -229,7 +239,8 @@ HANDLE duplicate_shell_token() {
return new_token;
}
PTOKEN_USER get_token_user(HANDLE token) {
PTOKEN_USER
get_token_user(HANDLE token) {
DWORD return_length;
if (GetTokenInformation(token, TokenUser, NULL, 0, &return_length) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
auto winerr = GetLastError();
@ -252,11 +263,13 @@ PTOKEN_USER get_token_user(HANDLE token) {
return user;
}
void free_token_user(PTOKEN_USER user) {
void
free_token_user(PTOKEN_USER user) {
HeapFree(GetProcessHeap(), 0, user);
}
bool is_token_same_user_as_process(HANDLE other_token) {
bool
is_token_same_user_as_process(HANDLE other_token) {
HANDLE process_token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token)) {
auto winerr = GetLastError();
@ -284,7 +297,8 @@ bool is_token_same_user_as_process(HANDLE other_token) {
return ret;
}
bool merge_user_environment_block(bp::environment &env, HANDLE shell_token) {
bool
merge_user_environment_block(bp::environment &env, HANDLE shell_token) {
// Get the target user's environment block
PVOID env_block;
if (!CreateEnvironmentBlock(&env_block, shell_token, FALSE)) {
@ -321,12 +335,14 @@ bool merge_user_environment_block(bp::environment &env, HANDLE shell_token) {
}
// Note: This does NOT append a null terminator
void append_string_to_environment_block(wchar_t *env_block, int &offset, const std::wstring &wstr) {
void
append_string_to_environment_block(wchar_t *env_block, int &offset, const std::wstring &wstr) {
std::memcpy(&env_block[offset], wstr.data(), wstr.length() * sizeof(wchar_t));
offset += wstr.length();
}
std::wstring create_environment_block(bp::environment &env) {
std::wstring
create_environment_block(bp::environment &env) {
int size = 0;
for (const auto &entry : env) {
auto name = entry.get_name();
@ -355,7 +371,8 @@ std::wstring create_environment_block(bp::environment &env) {
return std::wstring(env_block, offset);
}
LPPROC_THREAD_ATTRIBUTE_LIST allocate_proc_thread_attr_list(DWORD attribute_count) {
LPPROC_THREAD_ATTRIBUTE_LIST
allocate_proc_thread_attr_list(DWORD attribute_count) {
SIZE_T size;
InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size);
@ -372,12 +389,14 @@ LPPROC_THREAD_ATTRIBUTE_LIST allocate_proc_thread_attr_list(DWORD attribute_coun
return list;
}
void free_proc_thread_attr_list(LPPROC_THREAD_ATTRIBUTE_LIST list) {
void
free_proc_thread_attr_list(LPPROC_THREAD_ATTRIBUTE_LIST list) {
DeleteProcThreadAttributeList(list);
HeapFree(GetProcessHeap(), 0, list);
}
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
bp::child
run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
HANDLE shell_token = duplicate_shell_token();
if (!shell_token) {
// This can happen if the shell has crashed. Fail the launch rather than risking launching with
@ -542,7 +561,8 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
}
}
void adjust_thread_priority(thread_priority_e priority) {
void
adjust_thread_priority(thread_priority_e priority) {
int win32_priority;
switch (priority) {
@ -569,7 +589,8 @@ void adjust_thread_priority(thread_priority_e priority) {
}
}
void streaming_will_start() {
void
streaming_will_start() {
static std::once_flag load_wlanapi_once_flag;
std::call_once(load_wlanapi_once_flag, []() {
// wlanapi.dll is not installed by default on Windows Server, so we load it dynamically
@ -671,7 +692,8 @@ void streaming_will_start() {
}
}
void streaming_will_stop() {
void
streaming_will_stop() {
// Demote ourselves back to normal priority class
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
@ -697,19 +719,22 @@ void streaming_will_stop() {
}
}
bool restart_supported() {
bool
restart_supported() {
// Restart is supported if we're running from the service
return (GetConsoleWindow() == NULL);
}
bool restart() {
bool
restart() {
// Raise SIGINT to trigger the graceful exit logic. The service will
// restart us in a few seconds.
std::raise(SIGINT);
return true;
}
SOCKADDR_IN to_sockaddr(boost::asio::ip::address_v4 address, uint16_t port) {
SOCKADDR_IN
to_sockaddr(boost::asio::ip::address_v4 address, uint16_t port) {
SOCKADDR_IN saddr_v4 = {};
saddr_v4.sin_family = AF_INET;
@ -721,7 +746,8 @@ SOCKADDR_IN to_sockaddr(boost::asio::ip::address_v4 address, uint16_t port) {
return saddr_v4;
}
SOCKADDR_IN6 to_sockaddr(boost::asio::ip::address_v6 address, uint16_t port) {
SOCKADDR_IN6
to_sockaddr(boost::asio::ip::address_v6 address, uint16_t port) {
SOCKADDR_IN6 saddr_v6 = {};
saddr_v6.sin6_family = AF_INET6;
@ -736,7 +762,8 @@ SOCKADDR_IN6 to_sockaddr(boost::asio::ip::address_v6 address, uint16_t port) {
// Use UDP segmentation offload if it is supported by the OS. If the NIC is capable, this will use
// hardware acceleration to reduce CPU usage. Support for USO was introduced in Windows 10 20H1.
bool send_batch(batched_send_info_t &send_info) {
bool
send_batch(batched_send_info_t &send_info) {
WSAMSG msg;
// Convert the target address into a SOCKADDR
@ -784,7 +811,8 @@ bool send_batch(batched_send_info_t &send_info) {
class qos_t: public deinit_t {
public:
qos_t(QOS_FLOWID flow_id) : flow_id(flow_id) {}
qos_t(QOS_FLOWID flow_id):
flow_id(flow_id) {}
virtual ~qos_t() {
if (!fn_QOSRemoveSocketFromFlow(qos_handle, (SOCKET) NULL, flow_id, 0)) {
@ -797,7 +825,8 @@ private:
QOS_FLOWID flow_id;
};
std::unique_ptr<deinit_t> enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
std::unique_ptr<deinit_t>
enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type) {
SOCKADDR_IN saddr_v4;
SOCKADDR_IN6 saddr_v6;
PSOCKADDR dest_addr;

View file

@ -6,8 +6,10 @@
#include <winnt.h>
namespace platf {
void print_status(const std::string_view &prefix, HRESULT status);
HDESK syncThreadDesktop();
void
print_status(const std::string_view &prefix, HRESULT status);
HDESK
syncThreadDesktop();
} // namespace platf
#endif

View file

@ -59,7 +59,8 @@ typedef struct _DNS_SERVICE_INSTANCE {
} DNS_SERVICE_INSTANCE, *PDNS_SERVICE_INSTANCE;
#endif
typedef VOID WINAPI DNS_SERVICE_REGISTER_COMPLETE(
typedef VOID WINAPI
DNS_SERVICE_REGISTER_COMPLETE(
_In_ DWORD Status,
_In_ PVOID pQueryContext,
_In_ PDNS_SERVICE_INSTANCE pInstance);
@ -88,7 +89,8 @@ _FN(_DnsServiceRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _I
} /* extern "C" */
namespace platf::publish {
VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) {
VOID WINAPI
register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) {
auto alarm = (safe::alarm_t<PDNS_SERVICE_INSTANCE>::element_type *) pQueryContext;
if (status) {
@ -98,7 +100,8 @@ VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE
alarm->ring(pInstance);
}
static int service(bool enable, PDNS_SERVICE_INSTANCE &existing_instance) {
static int
service(bool enable, PDNS_SERVICE_INSTANCE &existing_instance) {
auto alarm = safe::make_alarm<PDNS_SERVICE_INSTANCE>();
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
@ -154,7 +157,8 @@ static int service(bool enable, PDNS_SERVICE_INSTANCE &existing_instance) {
class mdns_registration_t: public ::platf::deinit_t {
public:
mdns_registration_t() : existing_instance(nullptr) {
mdns_registration_t():
existing_instance(nullptr) {
if (service(true, existing_instance)) {
BOOST_LOG(error) << "Unable to register Sunshine mDNS service"sv;
return;
@ -178,7 +182,8 @@ private:
PDNS_SERVICE_INSTANCE existing_instance;
};
int load_funcs(HMODULE handle) {
int
load_funcs(HMODULE handle) {
auto fg = util::fail_guard([handle]() {
FreeLibrary(handle);
});
@ -196,7 +201,8 @@ int load_funcs(HMODULE handle) {
return 0;
}
std::unique_ptr<::platf::deinit_t> start() {
std::unique_ptr<::platf::deinit_t>
start() {
HMODULE handle = LoadLibrary("dnsapi.dll");
if (!handle || load_funcs(handle)) {

View file

@ -38,7 +38,8 @@ namespace pt = boost::property_tree;
proc_t proc;
void process_end(bp::child &proc, bp::group &proc_handle) {
void
process_end(bp::child &proc, bp::group &proc_handle) {
if (!proc.running()) {
return;
}
@ -50,7 +51,8 @@ void process_end(bp::child &proc, bp::group &proc_handle) {
proc.wait();
}
boost::filesystem::path find_working_directory(const std::string &cmd, bp::environment &env) {
boost::filesystem::path
find_working_directory(const std::string &cmd, bp::environment &env) {
// Parse the raw command string into parts to get the actual command portion
#ifdef _WIN32
auto parts = boost::program_options::split_winmain(cmd);
@ -80,7 +82,8 @@ boost::filesystem::path find_working_directory(const std::string &cmd, bp::envir
return cmd_path.parent_path();
}
int proc_t::execute(int app_id) {
int
proc_t::execute(int app_id) {
// Ensure starting from a clean slate
terminate();
@ -179,7 +182,8 @@ int proc_t::execute(int app_id) {
return 0;
}
int proc_t::running() {
int
proc_t::running() {
if (placebo || _process.running()) {
return _app_id;
}
@ -192,7 +196,8 @@ int proc_t::running() {
return 0;
}
void proc_t::terminate() {
void
proc_t::terminate() {
std::error_code ec;
// Ensure child process is terminated
@ -230,10 +235,12 @@ void proc_t::terminate() {
_pipe.reset();
}
const std::vector<ctx_t> &proc_t::get_apps() const {
const std::vector<ctx_t> &
proc_t::get_apps() const {
return _apps;
}
std::vector<ctx_t> &proc_t::get_apps() {
std::vector<ctx_t> &
proc_t::get_apps() {
return _apps;
}
@ -241,7 +248,8 @@ std::vector<ctx_t> &proc_t::get_apps() {
// Returns image from assets directory if found there.
// Returns default image if image configuration is not set.
// Returns http content-type header compatible image type.
std::string proc_t::get_app_image(int app_id) {
std::string
proc_t::get_app_image(int app_id) {
auto iter = std::find_if(_apps.begin(), _apps.end(), [&app_id](const auto app) {
return app.id == std::to_string(app_id);
});
@ -254,7 +262,8 @@ proc_t::~proc_t() {
terminate();
}
std::string_view::iterator find_match(std::string_view::iterator begin, std::string_view::iterator end) {
std::string_view::iterator
find_match(std::string_view::iterator begin, std::string_view::iterator end) {
int stack = 0;
--begin;
@ -275,7 +284,8 @@ std::string_view::iterator find_match(std::string_view::iterator begin, std::str
return begin;
}
std::string parse_env_val(bp::native_environment &env, const std::string_view &val_raw) {
std::string
parse_env_val(bp::native_environment &env, const std::string_view &val_raw) {
auto pos = std::begin(val_raw);
auto dollar = std::find(pos, std::end(val_raw), '$');
@ -329,7 +339,8 @@ std::string parse_env_val(bp::native_environment &env, const std::string_view &v
return ss.str();
}
std::string validate_app_image_path(std::string app_image_path) {
std::string
validate_app_image_path(std::string app_image_path) {
if (app_image_path.empty()) {
return DEFAULT_APP_IMAGE_PATH;
}
@ -366,7 +377,8 @@ std::string validate_app_image_path(std::string app_image_path) {
return app_image_path;
}
std::optional<std::string> calculate_sha256(const std::string &filename) {
std::optional<std::string>
calculate_sha256(const std::string &filename) {
crypto::md_ctx_t ctx { EVP_MD_CTX_create() };
if (!ctx) {
return std::nullopt;
@ -401,13 +413,15 @@ std::optional<std::string> calculate_sha256(const std::string &filename) {
return ss.str();
}
uint32_t calculate_crc32(const std::string &input) {
uint32_t
calculate_crc32(const std::string &input) {
boost::crc_32_type result;
result.process_bytes(input.data(), input.length());
return result.checksum();
}
std::tuple<std::string, std::string> calculate_app_id(const std::string &app_name, std::string app_image_path, int index) {
std::tuple<std::string, std::string>
calculate_app_id(const std::string &app_name, std::string app_image_path, int index) {
// Generate id by hashing name with image data if present
std::vector<std::string> to_hash;
to_hash.push_back(app_name);
@ -437,7 +451,8 @@ std::tuple<std::string, std::string> calculate_app_id(const std::string &app_nam
return std::make_tuple(id_no_index, id_with_index);
}
std::optional<proc::proc_t> parse(const std::string &file_name) {
std::optional<proc::proc_t>
parse(const std::string &file_name) {
pt::ptree tree;
try {
@ -550,7 +565,8 @@ std::optional<proc::proc_t> parse(const std::string &file_name) {
return std::nullopt;
}
void refresh(const std::string &file_name) {
void
refresh(const std::string &file_name) {
auto proc_opt = proc::parse(file_name);
if (proc_opt) {

View file

@ -56,24 +56,31 @@ public:
proc_t(
boost::process::environment &&env,
std::vector<ctx_t> &&apps) : _app_id(0),
std::vector<ctx_t> &&apps):
_app_id(0),
_env(std::move(env)),
_apps(std::move(apps)) {}
int execute(int app_id);
int
execute(int app_id);
/**
* @return _app_id if a process is running, otherwise returns 0
*/
int running();
int
running();
~proc_t();
const std::vector<ctx_t> &get_apps() const;
std::vector<ctx_t> &get_apps();
std::string get_app_image(int app_id);
const std::vector<ctx_t> &
get_apps() const;
std::vector<ctx_t> &
get_apps();
std::string
get_app_image(int app_id);
void terminate();
void
terminate();
private:
int _app_id;
@ -97,11 +104,15 @@ private:
* Calculate a stable id based on name and image data
* @return tuple of id calculated without index (for use if no collision) and one with
*/
std::tuple<std::string, std::string> calculate_app_id(const std::string &app_name, std::string app_image_path, int index);
std::tuple<std::string, std::string>
calculate_app_id(const std::string &app_name, std::string app_image_path, int index);
std::string validate_app_image_path(std::string app_image_path);
void refresh(const std::string &file_name);
std::optional<proc::proc_t> parse(const std::string &file_name);
std::string
validate_app_image_path(std::string app_image_path);
void
refresh(const std::string &file_name);
std::optional<proc::proc_t>
parse(const std::string &file_name);
extern proc_t proc;
} // namespace proc

View file

@ -16,7 +16,8 @@ public:
typedef T iterator;
typedef std::ptrdiff_t diff_t;
iterator operator+=(diff_t step) {
iterator
operator+=(diff_t step) {
while (step-- > 0) {
++_this();
}
@ -24,7 +25,8 @@ public:
return _this();
}
iterator operator-=(diff_t step) {
iterator
operator-=(diff_t step) {
while (step-- > 0) {
--_this();
}
@ -32,19 +34,22 @@ public:
return _this();
}
iterator operator+(diff_t step) {
iterator
operator+(diff_t step) {
iterator new_ = _this();
return new_ += step;
}
iterator operator-(diff_t step) {
iterator
operator-(diff_t step) {
iterator new_ = _this();
return new_ -= step;
}
diff_t operator-(iterator first) {
diff_t
operator-(iterator first) {
diff_t step = 0;
while (first != _this()) {
++step;
@ -54,16 +59,19 @@ public:
return step;
}
iterator operator++() {
iterator
operator++() {
_this().inc();
return _this();
}
iterator operator--() {
iterator
operator--() {
_this().dec();
return _this();
}
iterator operator++(int) {
iterator
operator++(int) {
iterator new_ = _this();
++_this();
@ -71,7 +79,8 @@ public:
return new_;
}
iterator operator--(int) {
iterator
operator--(int) {
iterator new_ = _this();
--_this();
@ -79,34 +88,46 @@ public:
return new_;
}
reference operator*() { return *_this().get(); }
const reference operator*() const { return *_this().get(); }
reference
operator*() { return *_this().get(); }
const reference
operator*() const { return *_this().get(); }
pointer operator->() { return &*_this(); }
const pointer operator->() const { return &*_this(); }
pointer
operator->() { return &*_this(); }
const pointer
operator->() const { return &*_this(); }
bool operator!=(const iterator &other) const {
bool
operator!=(const iterator &other) const {
return !(_this() == other);
}
bool operator<(const iterator &other) const {
bool
operator<(const iterator &other) const {
return !(_this() >= other);
}
bool operator>=(const iterator &other) const {
bool
operator>=(const iterator &other) const {
return _this() == other || _this() > other;
}
bool operator<=(const iterator &other) const {
bool
operator<=(const iterator &other) const {
return _this() == other || _this() < other;
}
bool operator==(const iterator &other) const { return _this().eq(other); };
bool operator>(const iterator &other) const { return _this().gt(other); }
bool
operator==(const iterator &other) const { return _this().eq(other); };
bool
operator>(const iterator &other) const { return _this().gt(other); }
private:
iterator &_this() { return *static_cast<iterator *>(this); }
const iterator &_this() const { return *static_cast<const iterator *>(this); }
iterator &
_this() { return *static_cast<iterator *>(this); }
const iterator &
_this() const { return *static_cast<const iterator *>(this); }
};
template <class V, class It>
@ -115,9 +136,11 @@ public:
using iterator = It;
using pointer = V *;
round_robin_t(iterator begin, iterator end) : _begin(begin), _end(end), _pos(begin) {}
round_robin_t(iterator begin, iterator end):
_begin(begin), _end(end), _pos(begin) {}
void inc() {
void
inc() {
++_pos;
if (_pos == _end) {
@ -125,7 +148,8 @@ public:
}
}
void dec() {
void
dec() {
if (_pos == _begin) {
_pos = _end;
}
@ -133,11 +157,13 @@ public:
--_pos;
}
bool eq(const round_robin_t &other) const {
bool
eq(const round_robin_t &other) const {
return *_pos == *other._pos;
}
pointer get() const {
pointer
get() const {
return &*_pos;
}
@ -149,7 +175,8 @@ private:
};
template <class V, class It>
round_robin_t<V, It> make_round_robin(It begin, It end) {
round_robin_t<V, It>
make_round_robin(It begin, It end) {
return round_robin_t<V, It>(begin, end);
}
} // namespace round_robin_util

View file

@ -30,7 +30,8 @@ using asio::ip::udp;
using namespace std::literals;
namespace rtsp_stream {
void free_msg(PRTSP_MESSAGE msg) {
void
free_msg(PRTSP_MESSAGE msg) {
freeMessage(msg);
delete msg;
@ -41,16 +42,20 @@ class rtsp_server_t;
using msg_t = util::safe_ptr<RTSP_MESSAGE, free_msg>;
using cmd_func_t = std::function<void(rtsp_server_t *server, tcp::socket &, msg_t &&)>;
void print_msg(PRTSP_MESSAGE msg);
void cmd_not_found(tcp::socket &sock, msg_t &&req);
void respond(tcp::socket &sock, POPTION_ITEM options, int statuscode, const char *status_msg, int seqn, const std::string_view &payload);
void
print_msg(PRTSP_MESSAGE msg);
void
cmd_not_found(tcp::socket &sock, msg_t &&req);
void
respond(tcp::socket &sock, POPTION_ITEM options, int statuscode, const char *status_msg, int seqn, const std::string_view &payload);
class socket_t: public std::enable_shared_from_this<socket_t> {
public:
socket_t(boost::asio::io_service &ios, std::function<void(tcp::socket &sock, msg_t &&)> &&handle_data_fn)
: handle_data_fn { std::move(handle_data_fn) }, sock { ios } {}
socket_t(boost::asio::io_service &ios, std::function<void(tcp::socket &sock, msg_t &&)> &&handle_data_fn):
handle_data_fn { std::move(handle_data_fn) }, sock { ios } {}
void read() {
void
read() {
if (begin == std::end(msg_buf)) {
BOOST_LOG(error) << "RTSP: read(): Exceeded maximum rtsp packet size: "sv << msg_buf.size();
@ -69,7 +74,8 @@ public:
boost::asio::placeholders::bytes_transferred));
}
void read_payload() {
void
read_payload() {
if (begin == std::end(msg_buf)) {
BOOST_LOG(error) << "RTSP: read_payload(): Exceeded maximum rtsp packet size: "sv << msg_buf.size();
@ -88,7 +94,8 @@ public:
boost::asio::placeholders::bytes_transferred));
}
static void handle_payload(std::shared_ptr<socket_t> &socket, const boost::system::error_code &ec, std::size_t bytes) {
static void
handle_payload(std::shared_ptr<socket_t> &socket, const boost::system::error_code &ec, std::size_t bytes) {
BOOST_LOG(debug) << "handle_payload(): Handle read of size: "sv << bytes << " bytes"sv;
auto sock_close = util::fail_guard([&socket]() {
@ -150,7 +157,8 @@ public:
socket->begin = end;
}
static void handle_read(std::shared_ptr<socket_t> &socket, const boost::system::error_code &ec, std::size_t bytes) {
static void
handle_read(std::shared_ptr<socket_t> &socket, const boost::system::error_code &ec, std::size_t bytes) {
BOOST_LOG(debug) << "handle_read(): Handle read of size: "sv << bytes << " bytes"sv;
if (ec) {
@ -192,7 +200,8 @@ public:
handle_payload(socket, ec, buf_size);
}
void handle_data(msg_t &&req) {
void
handle_data(msg_t &&req) {
handle_data_fn(sock, std::move(req));
}
@ -212,7 +221,8 @@ public:
clear();
}
int bind(std::uint16_t port, boost::system::error_code &ec) {
int
bind(std::uint16_t port, boost::system::error_code &ec) {
{
auto lg = _session_slots.lock();
@ -249,11 +259,13 @@ public:
}
template <class T, class X>
void iterate(std::chrono::duration<T, X> timeout) {
void
iterate(std::chrono::duration<T, X> timeout) {
ios.run_one_for(timeout);
}
void handle_msg(tcp::socket &sock, msg_t &&req) {
void
handle_msg(tcp::socket &sock, msg_t &&req) {
auto func = _map_cmd_cb.find(req->message.request.command);
if (func != std::end(_map_cmd_cb)) {
func->second(this, sock, std::move(req));
@ -265,7 +277,8 @@ public:
sock.shutdown(boost::asio::socket_base::shutdown_type::shutdown_both);
}
void handle_accept(const boost::system::error_code &ec) {
void
handle_accept(const boost::system::error_code &ec) {
if (ec) {
BOOST_LOG(error) << "Couldn't accept incoming connections: "sv << ec.message();
@ -286,11 +299,13 @@ public:
});
}
void map(const std::string_view &type, cmd_func_t cb) {
void
map(const std::string_view &type, cmd_func_t cb) {
_map_cmd_cb.emplace(type, std::move(cb));
}
void session_raise(rtsp_stream::launch_session_t launch_session) {
void
session_raise(rtsp_stream::launch_session_t launch_session) {
auto now = std::chrono::steady_clock::now();
// If a launch event is still pending, don't overwrite it.
@ -303,13 +318,15 @@ public:
launch_event.raise(launch_session);
}
int session_count() const {
int
session_count() const {
return config::stream.channels - _slot_count;
}
safe::event_t<rtsp_stream::launch_session_t> launch_event;
void clear(bool all = true) {
void
clear(bool all = true) {
// if a launch event timed out --> Remove it.
if (raised_timeout < std::chrono::steady_clock::now()) {
auto discarded = launch_event.pop(0s);
@ -336,7 +353,8 @@ public:
}
}
void clear(std::shared_ptr<stream::session_t> *session_p) {
void
clear(std::shared_ptr<stream::session_t> *session_p) {
auto lg = _session_slots.lock();
session_p->reset();
@ -344,7 +362,8 @@ public:
++_slot_count;
}
std::shared_ptr<stream::session_t> *accept(std::shared_ptr<stream::session_t> &session) {
std::shared_ptr<stream::session_t> *
accept(std::shared_ptr<stream::session_t> &session) {
auto lg = _session_slots.lock();
for (auto &slot : *_session_slots) {
@ -373,18 +392,21 @@ private:
rtsp_server_t server {};
void launch_session_raise(rtsp_stream::launch_session_t launch_session) {
void
launch_session_raise(rtsp_stream::launch_session_t launch_session) {
server.session_raise(launch_session);
}
int session_count() {
int
session_count() {
// Ensure session_count is up-to-date
server.clear(false);
return server.session_count();
}
int send(tcp::socket &sock, const std::string_view &sv) {
int
send(tcp::socket &sock, const std::string_view &sv) {
std::size_t bytes_send = 0;
while (bytes_send != sv.size()) {
@ -400,7 +422,8 @@ int send(tcp::socket &sock, const std::string_view &sv) {
return 0;
}
void respond(tcp::socket &sock, msg_t &resp) {
void
respond(tcp::socket &sock, msg_t &resp) {
auto payload = std::make_pair(resp->payload, resp->payloadLength);
// Restore response message for proper destruction
@ -429,18 +452,21 @@ void respond(tcp::socket &sock, msg_t &resp) {
send(sock, std::string_view { payload.first, (std::size_t) payload.second });
}
void respond(tcp::socket &sock, POPTION_ITEM options, int statuscode, const char *status_msg, int seqn, const std::string_view &payload) {
void
respond(tcp::socket &sock, POPTION_ITEM options, int statuscode, const char *status_msg, int seqn, const std::string_view &payload) {
msg_t resp { new msg_t::element_type };
createRtspResponse(resp.get(), nullptr, 0, const_cast<char *>("RTSP/1.0"), statuscode, const_cast<char *>(status_msg), seqn, options, const_cast<char *>(payload.data()), (int) payload.size());
respond(sock, resp);
}
void cmd_not_found(tcp::socket &sock, msg_t &&req) {
void
cmd_not_found(tcp::socket &sock, msg_t &&req) {
respond(sock, nullptr, 404, "NOT FOUND", req->sequenceNumber, {});
}
void cmd_option(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
void
cmd_option(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
OPTION_ITEM option {};
// I know these string literals will not be modified
@ -452,7 +478,8 @@ void cmd_option(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
respond(sock, &option, 200, "OK", req->sequenceNumber, {});
}
void cmd_describe(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
void
cmd_describe(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
OPTION_ITEM option {};
// I know these string literals will not be modified
@ -496,7 +523,8 @@ void cmd_describe(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
respond(sock, &option, 200, "OK", req->sequenceNumber, ss.str());
}
void cmd_setup(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
void
cmd_setup(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
OPTION_ITEM options[3] {};
auto &seqn = options[0];
@ -542,11 +570,11 @@ void cmd_setup(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
port_option.option = const_cast<char *>("Transport");
port_option.content = port_value.data();
respond(sock, &seqn, 200, "OK", req->sequenceNumber, {});
}
void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
void
cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
OPTION_ITEM option {};
// I know these string literals will not be modified
@ -645,7 +673,6 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
config.monitor.dynamicRange = util::from_view(args.at("x-nv-video[0].dynamicRangeMode"sv));
}
catch (std::out_of_range &) {
respond(sock, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
return;
}
@ -691,7 +718,8 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
respond(sock, &option, 200, "OK", req->sequenceNumber, {});
}
void cmd_play(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
void
cmd_play(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
OPTION_ITEM option {};
// I know these string literals will not be modified
@ -703,7 +731,8 @@ void cmd_play(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) {
respond(sock, &option, 200, "OK", req->sequenceNumber, {});
}
void rtpThread() {
void
rtpThread() {
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
@ -737,7 +766,8 @@ void rtpThread() {
server.clear();
}
void print_msg(PRTSP_MESSAGE msg) {
void
print_msg(PRTSP_MESSAGE msg) {
std::string_view type = msg->type == TYPE_RESPONSE ? "RESPONSE"sv : "REQUEST"sv;
std::string_view payload { msg->payload, (size_t) msg->payloadLength };

View file

@ -18,10 +18,13 @@ struct launch_session_t {
bool host_audio;
};
void launch_session_raise(launch_session_t launch_session);
int session_count();
void
launch_session_raise(launch_session_t launch_session);
int
session_count();
void rtpThread();
void
rtpThread();
} // namespace rtsp_stream

View file

@ -68,7 +68,8 @@ enum class socket_e : int {
#pragma pack(push, 1)
struct video_short_frame_header_t {
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
@ -90,7 +91,8 @@ static_assert(
"Short frame header must be 8 bytes");
struct video_packet_raw_t {
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
@ -101,7 +103,8 @@ struct video_packet_raw_t {
};
struct audio_packet_raw_t {
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
@ -112,7 +115,8 @@ struct control_header_v2 {
std::uint16_t type;
std::uint16_t payloadLength;
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
};
@ -149,14 +153,16 @@ typedef struct control_encrypted_t {
// seq is accepted as an arbitrary value in Moonlight
std::uint32_t seq; // Monotonically increasing sequence number (used as IV for AES-GCM)
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
// encrypted control_header_v2 and payload data follow
} *control_encrypted_p;
struct audio_fec_packet_raw_t {
uint8_t *payload() {
uint8_t *
payload() {
return (uint8_t *) (this + 1);
}
@ -166,7 +172,8 @@ struct audio_fec_packet_raw_t {
#pragma pack(pop)
constexpr std::size_t round_to_pkcs7_padded(std::size_t size) {
constexpr std::size_t
round_to_pkcs7_padded(std::size_t size) {
return ((size + 15) / 16) * 16;
}
constexpr std::size_t MAX_AUDIO_PACKET_SIZE = 1400;
@ -182,7 +189,8 @@ using message_queue_queue_t = std::shared_ptr<safe::queue_t<std::tuple<socket_e,
// return bytes written on success
// return -1 on error
static inline int encode_audio(int featureSet, const audio::buffer_t &plaintext, audio_packet_t &destination, std::uint32_t avRiKeyIv, crypto::cipher::cbc_t &cbc) {
static inline int
encode_audio(int featureSet, const audio::buffer_t &plaintext, audio_packet_t &destination, std::uint32_t avRiKeyIv, crypto::cipher::cbc_t &cbc) {
// If encryption isn't enabled
if (!(featureSet & 0x20)) {
std::copy(std::begin(plaintext), std::end(plaintext), destination->payload());
@ -195,7 +203,8 @@ static inline int encode_audio(int featureSet, const audio::buffer_t &plaintext,
return cbc.encrypt(std::string_view { (char *) std::begin(plaintext), plaintext.size() }, destination->payload(), &iv);
}
static inline void while_starting_do_nothing(std::atomic<session::state_e> &state) {
static inline void
while_starting_do_nothing(std::atomic<session::state_e> &state) {
while (state.load(std::memory_order_acquire) == session::state_e::STARTING) {
std::this_thread::sleep_for(1ms);
}
@ -203,13 +212,15 @@ static inline void while_starting_do_nothing(std::atomic<session::state_e> &stat
class control_server_t {
public:
int bind(std::uint16_t port) {
int
bind(std::uint16_t port) {
_host = net::host_create(_addr, config::stream.channels, port);
return !(bool) _host;
}
void emplace_addr_to_session(const std::string &addr, session_t &session) {
void
emplace_addr_to_session(const std::string &addr, session_t &session) {
auto lg = _map_addr_session.lock();
_map_addr_session->emplace(addr, std::make_pair(0u, &session));
@ -218,22 +229,27 @@ public:
// Get session associated with address.
// If none are found, try to find a session not yet claimed. (It will be marked by a port of value 0
// If none of those are found, return nullptr
session_t *get_session(const net::peer_t peer);
session_t *
get_session(const net::peer_t peer);
// Circular dependency:
// iterate refers to session
// session refers to broadcast_ctx_t
// broadcast_ctx_t refers to control_server_t
// Therefore, iterate is implemented further down the source file
void iterate(std::chrono::milliseconds timeout);
void
iterate(std::chrono::milliseconds timeout);
void call(std::uint16_t type, session_t *session, const std::string_view &payload);
void
call(std::uint16_t type, session_t *session, const std::string_view &payload);
void map(uint16_t type, std::function<void(session_t *, const std::string_view &)> cb) {
void
map(uint16_t type, std::function<void(session_t *, const std::string_view &)> cb) {
_map_type_cb.emplace(type, std::move(cb));
}
int send(const std::string_view &payload, net::peer_t peer) {
int
send(const std::string_view &payload, net::peer_t peer) {
auto packet = enet_packet_create(payload.data(), payload.size(), ENET_PACKET_FLAG_RELIABLE);
if (enet_peer_send(peer, 0, packet)) {
enet_packet_destroy(packet);
@ -244,7 +260,8 @@ public:
return 0;
}
void flush() {
void
flush() {
enet_host_flush(_host.get());
}
@ -341,12 +358,12 @@ struct session_t {
* returns string_view pointing to payload data
*/
template <std::size_t max_payload_size>
static inline std::string_view encode_control(session_t *session, const std::string_view &plaintext, std::array<std::uint8_t, max_payload_size> &tagged_cipher) {
static inline std::string_view
encode_control(session_t *session, const std::string_view &plaintext, std::array<std::uint8_t, max_payload_size> &tagged_cipher) {
static_assert(
max_payload_size >= sizeof(control_encrypted_t) + sizeof(crypto::cipher::tag_size),
"max_payload_size >= sizeof(control_encrypted_t) + sizeof(crypto::cipher::tag_size)");
if (session->config.controlProtocolType != 13) {
return plaintext;
}
@ -372,13 +389,15 @@ static inline std::string_view encode_control(session_t *session, const std::str
return std::string_view { (char *) tagged_cipher.data(), packet_length + sizeof(control_encrypted_t) - sizeof(control_encrypted_t::seq) };
}
int start_broadcast(broadcast_ctx_t &ctx);
void end_broadcast(broadcast_ctx_t &ctx);
int
start_broadcast(broadcast_ctx_t &ctx);
void
end_broadcast(broadcast_ctx_t &ctx);
static auto broadcast = safe::make_shared<broadcast_ctx_t>(start_broadcast, end_broadcast);
session_t *control_server_t::get_session(const net::peer_t peer) {
session_t *
control_server_t::get_session(const net::peer_t peer) {
TUPLE_2D(port, addr_string, platf::from_sockaddr_ex((sockaddr *) &peer->address.address));
auto lg = _map_addr_session.lock();
@ -408,7 +427,8 @@ session_t *control_server_t::get_session(const net::peer_t peer) {
return nullptr;
}
void control_server_t::call(std::uint16_t type, session_t *session, const std::string_view &payload) {
void
control_server_t::call(std::uint16_t type, session_t *session, const std::string_view &payload) {
auto cb = _map_type_cb.find(type);
if (cb == std::end(_map_type_cb)) {
BOOST_LOG(debug)
@ -422,7 +442,8 @@ void control_server_t::call(std::uint16_t type, session_t *session, const std::s
}
}
void control_server_t::iterate(std::chrono::milliseconds timeout) {
void
control_server_t::iterate(std::chrono::milliseconds timeout) {
ENetEvent event;
auto res = enet_host_service(_host.get(), &event, timeout.count());
@ -473,20 +494,24 @@ struct fec_t {
size_t blocksize;
util::buffer_t<char> shards;
char *data(size_t el) {
char *
data(size_t el) {
return &shards[el * blocksize];
}
std::string_view operator[](size_t el) const {
std::string_view
operator[](size_t el) const {
return { &shards[el * blocksize], blocksize };
}
size_t size() const {
size_t
size() const {
return nr_shards;
}
};
static fec_t encode(const std::string_view &payload, size_t blocksize, size_t fecpercentage, size_t minparityshards) {
static fec_t
encode(const std::string_view &payload, size_t blocksize, size_t fecpercentage, size_t minparityshards) {
auto payload_size = payload.size();
auto pad = payload_size % blocksize != 0;
@ -542,7 +567,8 @@ static fec_t encode(const std::string_view &payload, size_t blocksize, size_t fe
} // namespace fec
template <class F>
std::vector<uint8_t> insert(uint64_t insert_size, uint64_t slice_size, const std::string_view &data, F &&f) {
std::vector<uint8_t>
insert(uint64_t insert_size, uint64_t slice_size, const std::string_view &data, F &&f) {
auto pad = data.size() % slice_size != 0;
auto elements = data.size() / slice_size + (pad ? 1 : 0);
@ -569,7 +595,8 @@ std::vector<uint8_t> insert(uint64_t insert_size, uint64_t slice_size, const std
return result;
}
std::vector<uint8_t> replace(const std::string_view &original, const std::string_view &old, const std::string_view &_new) {
std::vector<uint8_t>
replace(const std::string_view &original, const std::string_view &old, const std::string_view &_new) {
std::vector<uint8_t> replaced;
auto begin = std::begin(original);
@ -585,7 +612,8 @@ std::vector<uint8_t> replace(const std::string_view &original, const std::string
return replaced;
}
int send_rumble(session_t *session, std::uint16_t id, std::uint16_t lowfreq, std::uint16_t highfreq) {
int
send_rumble(session_t *session, std::uint16_t id, std::uint16_t lowfreq, std::uint16_t highfreq) {
if (!session->control.peer) {
BOOST_LOG(warning) << "Couldn't send rumble data, still waiting for PING from Moonlight"sv;
// Still waiting for PING from Moonlight
@ -619,7 +647,8 @@ int send_rumble(session_t *session, std::uint16_t id, std::uint16_t lowfreq, std
return 0;
}
int send_hdr_mode(session_t *session, video::hdr_info_t hdr_info) {
int
send_hdr_mode(session_t *session, video::hdr_info_t hdr_info) {
if (!session->control.peer) {
BOOST_LOG(warning) << "Couldn't send HDR mode, still waiting for PING from Moonlight"sv;
// Still waiting for PING from Moonlight
@ -649,7 +678,8 @@ int send_hdr_mode(session_t *session, video::hdr_info_t hdr_info) {
return 0;
}
void controlBroadcastThread(control_server_t *server) {
void
controlBroadcastThread(control_server_t *server) {
server->map(packetTypes[IDX_PERIODIC_PING], [](session_t *session, const std::string_view &payload) {
BOOST_LOG(verbose) << "type [IDX_START_A]"sv;
});
@ -874,7 +904,8 @@ void controlBroadcastThread(control_server_t *server) {
server->flush();
}
void recvThread(broadcast_ctx_t &ctx) {
void
recvThread(broadcast_ctx_t &ctx) {
std::map<asio::ip::address, message_queue_t> peer_to_video_session;
std::map<asio::ip::address, message_queue_t> peer_to_audio_session;
@ -926,7 +957,6 @@ void recvThread(broadcast_ctx_t &ctx) {
auto type_str = buf_elem ? "AUDIO"sv : "VIDEO"sv;
BOOST_LOG(verbose) << "Recv: "sv << peer.address().to_string() << ':' << peer.port() << " :: " << type_str;
populate_peer_to_session();
// No data, yet no error
@ -958,7 +988,8 @@ void recvThread(broadcast_ctx_t &ctx) {
}
}
void videoBroadcastThread(udp::socket &sock) {
void
videoBroadcastThread(udp::socket &sock) {
auto shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
auto packets = mail::man->queue<video::packet_t>(mail::video_packets);
auto timebase = boost::posix_time::microsec_clock::universal_time();
@ -1135,7 +1166,8 @@ void videoBroadcastThread(udp::socket &sock) {
shutdown_event->raise(true);
}
void audioBroadcastThread(udp::socket &sock) {
void
audioBroadcastThread(udp::socket &sock) {
auto shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
auto packets = mail::man->queue<audio::packet_t>(mail::audio_packets);
@ -1192,7 +1224,6 @@ void audioBroadcastThread(udp::socket &sock) {
try {
sock.send_to(asio::buffer((char *) audio_packet.get(), sizeof(audio_packet_raw_t) + bytes), session->audio.peer);
BOOST_LOG(verbose) << "Audio ["sv << sequenceNumber << "] :: send..."sv;
auto &fec_packet = session->audio.fec_packet;
@ -1224,7 +1255,8 @@ void audioBroadcastThread(udp::socket &sock) {
shutdown_event->raise(true);
}
int start_broadcast(broadcast_ctx_t &ctx) {
int
start_broadcast(broadcast_ctx_t &ctx) {
auto control_port = map_port(CONTROL_PORT);
auto video_port = map_port(VIDEO_STREAM_PORT);
auto audio_port = map_port(AUDIO_STREAM_PORT);
@ -1275,7 +1307,8 @@ int start_broadcast(broadcast_ctx_t &ctx) {
return 0;
}
void end_broadcast(broadcast_ctx_t &ctx) {
void
end_broadcast(broadcast_ctx_t &ctx) {
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
broadcast_shutdown_event->raise(true);
@ -1309,7 +1342,8 @@ void end_broadcast(broadcast_ctx_t &ctx) {
broadcast_shutdown_event->reset();
}
int recv_ping(decltype(broadcast)::ptr_t ref, socket_e type, udp::endpoint &peer, std::chrono::milliseconds timeout) {
int
recv_ping(decltype(broadcast)::ptr_t ref, socket_e type, udp::endpoint &peer, std::chrono::milliseconds timeout) {
auto constexpr ping = "PING"sv;
auto messages = std::make_shared<message_queue_t::element_type>(30);
@ -1378,7 +1412,8 @@ int recv_ping(decltype(broadcast)::ptr_t ref, socket_e type, udp::endpoint &peer
return -1;
}
void videoThread(session_t *session) {
void
videoThread(session_t *session) {
auto fg = util::fail_guard([&]() {
session::stop(*session);
});
@ -1402,7 +1437,8 @@ void videoThread(session_t *session) {
video::capture(session->mail, session->config.monitor, session);
}
void audioThread(session_t *session) {
void
audioThread(session_t *session) {
auto fg = util::fail_guard([&]() {
session::stop(*session);
});
@ -1429,11 +1465,13 @@ void audioThread(session_t *session) {
namespace session {
std::atomic_uint running_sessions;
state_e state(session_t &session) {
state_e
state(session_t &session) {
return session.state.load(std::memory_order_relaxed);
}
void stop(session_t &session) {
void
stop(session_t &session) {
while_starting_do_nothing(session.state);
auto expected = state_e::RUNNING;
auto already_stopping = !session.state.compare_exchange_strong(expected, state_e::STOPPING);
@ -1444,7 +1482,8 @@ void stop(session_t &session) {
session.shutdown_event->raise(true);
}
void join(session_t &session) {
void
join(session_t &session) {
// Current Nvidia drivers have a bug where NVENC can deadlock the encoder thread with hardware-accelerated
// GPU scheduling enabled. If this happens, we will terminate ourselves and the service can restart.
// The alternative is that Sunshine can never start another session until it's manually restarted.
@ -1512,7 +1551,8 @@ void join(session_t &session) {
BOOST_LOG(debug) << "Session ended"sv;
}
int start(session_t &session, const std::string &addr_string) {
int
start(session_t &session, const std::string &addr_string) {
session.input = input::alloc(session.mail);
session.broadcast_ref = broadcast.ref();
@ -1539,7 +1579,6 @@ int start(session_t &session, const std::string &addr_string) {
connections->emplace_back(addr_string, 0);
}
session.pingTimeout = std::chrono::steady_clock::now() + config::stream.ping_timeout;
session.audioThread = std::thread { audioThread, &session };
@ -1555,7 +1594,8 @@ int start(session_t &session, const std::string &addr_string) {
return 0;
}
std::shared_ptr<session_t> alloc(config_t &config, crypto::aes_t &gcm_key, crypto::aes_t &iv) {
std::shared_ptr<session_t>
alloc(config_t &config, crypto::aes_t &gcm_key, crypto::aes_t &iv) {
auto session = std::make_shared<session_t>();
auto mail = std::make_shared<safe::mail_raw_t>();

View file

@ -37,11 +37,16 @@ enum class state_e : int {
RUNNING,
};
std::shared_ptr<session_t> alloc(config_t &config, crypto::aes_t &gcm_key, crypto::aes_t &iv);
int start(session_t &session, const std::string &addr_string);
void stop(session_t &session);
void join(session_t &session);
state_e state(session_t &session);
std::shared_ptr<session_t>
alloc(config_t &config, crypto::aes_t &gcm_key, crypto::aes_t &iv);
int
start(session_t &session, const std::string &addr_string);
void
stop(session_t &session);
void
join(session_t &session);
state_e
state(session_t &session);
} // namespace session
} // namespace stream

View file

@ -15,14 +15,17 @@ public:
using value_t = T;
using mutex_t = M;
std::lock_guard<mutex_t> lock() {
std::lock_guard<mutex_t>
lock() {
return std::lock_guard { _lock };
}
template <class... Args>
sync_t(Args &&...args) : raw { std::forward<Args>(args)... } {}
sync_t(Args &&...args):
raw { std::forward<Args>(args)... } {}
sync_t &operator=(sync_t &&other) noexcept {
sync_t &
operator=(sync_t &&other) noexcept {
std::lock(_lock, other._lock);
raw = std::move(other.raw);
@ -33,7 +36,8 @@ public:
return *this;
}
sync_t &operator=(sync_t &other) noexcept {
sync_t &
operator=(sync_t &other) noexcept {
std::lock(_lock, other._lock);
raw = other.raw;
@ -45,7 +49,8 @@ public:
}
template <class V>
sync_t &operator=(V &&val) {
sync_t &
operator=(V &&val) {
auto lg = lock();
raw = val;
@ -53,7 +58,8 @@ public:
return *this;
}
sync_t &operator=(const value_t &val) noexcept {
sync_t &
operator=(const value_t &val) noexcept {
auto lg = lock();
raw = val;
@ -61,7 +67,8 @@ public:
return *this;
}
sync_t &operator=(value_t &&val) noexcept {
sync_t &
operator=(value_t &&val) noexcept {
auto lg = lock();
raw = std::move(val);
@ -69,15 +76,18 @@ public:
return *this;
}
value_t *operator->() {
value_t *
operator->() {
return &raw;
}
value_t &operator*() {
value_t &
operator*() {
return raw;
}
const value_t &operator*() const {
const value_t &
operator*() const {
return raw;
}
@ -89,5 +99,4 @@ private:
} // namespace sync_util
#endif // SUNSHINE_SYNC_H

View file

@ -37,7 +37,8 @@ namespace system_tray {
* @brief Open a url in the default web browser.
* @param url The url to open.
*/
void open_url(const std::string &url) {
void
open_url(const std::string &url) {
boost::filesystem::path working_dir;
// if windows
@ -70,7 +71,8 @@ void open_url(const std::string &url) {
* @brief Callback for opening the UI from the system tray.
* @param item The tray menu item.
*/
void tray_open_ui_cb(struct tray_menu *item) {
void
tray_open_ui_cb(struct tray_menu *item) {
BOOST_LOG(info) << "Opening UI from system tray"sv;
// create the url with the port
@ -84,7 +86,8 @@ void tray_open_ui_cb(struct tray_menu *item) {
* @brief Callback for opening GitHub Sponsors from the system tray.
* @param item The tray menu item.
*/
void tray_donate_github_cb(struct tray_menu *item) {
void
tray_donate_github_cb(struct tray_menu *item) {
open_url("https://github.com/sponsors/LizardByte");
}
@ -92,7 +95,8 @@ void tray_donate_github_cb(struct tray_menu *item) {
* @brief Callback for opening MEE6 donation from the system tray.
* @param item The tray menu item.
*/
void tray_donate_mee6_cb(struct tray_menu *item) {
void
tray_donate_mee6_cb(struct tray_menu *item) {
open_url("https://mee6.xyz/m/804382334370578482");
}
@ -100,7 +104,8 @@ void tray_donate_mee6_cb(struct tray_menu *item) {
* @brief Callback for opening Patreon from the system tray.
* @param item The tray menu item.
*/
void tray_donate_patreon_cb(struct tray_menu *item) {
void
tray_donate_patreon_cb(struct tray_menu *item) {
open_url("https://www.patreon.com/LizardByte");
}
@ -108,7 +113,8 @@ void tray_donate_patreon_cb(struct tray_menu *item) {
* @brief Callback for opening PayPal donation from the system tray.
* @param item The tray menu item.
*/
void tray_donate_paypal_cb(struct tray_menu *item) {
void
tray_donate_paypal_cb(struct tray_menu *item) {
open_url("https://www.paypal.com/paypalme/ReenigneArcher");
}
@ -116,7 +122,8 @@ void tray_donate_paypal_cb(struct tray_menu *item) {
* @brief Callback for exiting Sunshine from the system tray.
* @param item The tray menu item.
*/
void tray_quit_cb(struct tray_menu *item) {
void
tray_quit_cb(struct tray_menu *item) {
BOOST_LOG(info) << "Quiting from system tray"sv;
std::raise(SIGINT);
@ -146,13 +153,13 @@ static struct tray tray = {
{ .text = nullptr } },
};
/**
* @brief Create the system tray.
* @details This function has an endless loop, so it should be run in a separate thread.
* @return 1 if the system tray failed to create, otherwise 0 once the tray has been terminated.
*/
int system_tray() {
int
system_tray() {
if (tray_init(&tray) < 0) {
BOOST_LOG(warning) << "Failed to create system tray"sv;
return 1;
@ -172,7 +179,8 @@ int system_tray() {
* @brief Run the system tray with platform specific options.
* @note macOS requires that UI elements be created on the main thread, so the system tray is not implemented for macOS.
*/
void run_tray() {
void
run_tray() {
// create the system tray
#if defined(__APPLE__) || defined(__MACH__)
// macOS requires that UI elements be created on the main thread
@ -194,7 +202,8 @@ void run_tray() {
* @brief Exit the system tray.
* @return 0 after exiting the system tray.
*/
int end_tray() {
int
end_tray() {
tray_exit();
return 0;
}

View file

@ -7,17 +7,27 @@
// system_tray namespace
namespace system_tray {
void open_url(const std::string &url);
void tray_open_ui_cb(struct tray_menu *item);
void tray_donate_github_cb(struct tray_menu *item);
void tray_donate_mee6_cb(struct tray_menu *item);
void tray_donate_patreon_cb(struct tray_menu *item);
void tray_donate_paypal_cb(struct tray_menu *item);
void tray_quit_cb(struct tray_menu *item);
void
open_url(const std::string &url);
void
tray_open_ui_cb(struct tray_menu *item);
void
tray_donate_github_cb(struct tray_menu *item);
void
tray_donate_mee6_cb(struct tray_menu *item);
void
tray_donate_patreon_cb(struct tray_menu *item);
void
tray_donate_paypal_cb(struct tray_menu *item);
void
tray_quit_cb(struct tray_menu *item);
int system_tray();
int run_tray();
int end_tray();
int
system_tray();
int
run_tray();
int
end_tray();
} // namespace system_tray
#endif

View file

@ -21,7 +21,8 @@ public:
inline virtual ~_ImplBase() = default;
virtual void run() = 0;
virtual void
run() = 0;
};
template <class Function>
@ -29,9 +30,11 @@ class _Impl : public _ImplBase {
Function _func;
public:
_Impl(Function &&f) : _func(std::forward<Function>(f)) {}
_Impl(Function &&f):
_func(std::forward<Function>(f)) {}
void run() override {
void
run() override {
_func();
}
};
@ -41,7 +44,6 @@ public:
typedef std::unique_ptr<_ImplBase> __task;
typedef _ImplBase *task_id_t;
typedef std::chrono::steady_clock::time_point __time_point;
template <class R>
@ -50,7 +52,8 @@ public:
task_id_t task_id;
std::future<R> future;
timer_task_t(task_id_t task_id, std::future<R> &future) : task_id { task_id }, future { std::move(future) } {}
timer_task_t(task_id_t task_id, std::future<R> &future):
task_id { task_id }, future { std::move(future) } {}
};
protected:
@ -60,9 +63,11 @@ protected:
public:
TaskPool() = default;
TaskPool(TaskPool &&other) noexcept : _tasks { std::move(other._tasks) }, _timer_tasks { std::move(other._timer_tasks) } {}
TaskPool(TaskPool &&other) noexcept:
_tasks { std::move(other._tasks) }, _timer_tasks { std::move(other._timer_tasks) } {}
TaskPool &operator=(TaskPool &&other) noexcept {
TaskPool &
operator=(TaskPool &&other) noexcept {
std::swap(_tasks, other._tasks);
std::swap(_timer_tasks, other._timer_tasks);
@ -70,7 +75,8 @@ public:
}
template <class Function, class... Args>
auto push(Function &&newTask, Args &&...args) {
auto
push(Function &&newTask, Args &&...args) {
static_assert(std::is_invocable_v<Function, Args &&...>, "arguments don't match the function");
using __return = std::invoke_result_t<Function, Args &&...>;
@ -90,7 +96,8 @@ public:
return future;
}
void pushDelayed(std::pair<__time_point, __task> &&task) {
void
pushDelayed(std::pair<__time_point, __task> &&task) {
std::lock_guard lg(_task_mutex);
auto it = _timer_tasks.cbegin();
@ -107,7 +114,8 @@ public:
* @return an id to potentially delay the task
*/
template <class Function, class X, class Y, class... Args>
auto pushDelayed(Function &&newTask, std::chrono::duration<X, Y> duration, Args &&...args) {
auto
pushDelayed(Function &&newTask, std::chrono::duration<X, Y> duration, Args &&...args) {
static_assert(std::is_invocable_v<Function, Args &&...>, "arguments don't match the function");
using __return = std::invoke_result_t<Function, Args &&...>;
@ -141,7 +149,8 @@ public:
* @param duration The delay before executing the task
*/
template <class X, class Y>
void delay(task_id_t task_id, std::chrono::duration<X, Y> duration) {
void
delay(task_id_t task_id, std::chrono::duration<X, Y> duration) {
std::lock_guard<std::mutex> lg(_task_mutex);
auto it = _timer_tasks.begin();
@ -171,7 +180,8 @@ public:
}
}
bool cancel(task_id_t task_id) {
bool
cancel(task_id_t task_id) {
std::lock_guard lg(_task_mutex);
auto it = _timer_tasks.begin();
@ -188,7 +198,8 @@ public:
return false;
}
std::optional<std::pair<__time_point, __task>> pop(task_id_t task_id) {
std::optional<std::pair<__time_point, __task>>
pop(task_id_t task_id) {
std::lock_guard lg(_task_mutex);
auto pos = std::find_if(std::begin(_timer_tasks), std::end(_timer_tasks), [&task_id](const auto &t) { return t.second.get() == task_id; });
@ -200,7 +211,8 @@ public:
return std::move(*pos);
}
std::optional<__task> pop() {
std::optional<__task>
pop() {
std::lock_guard lg(_task_mutex);
if (!_tasks.empty()) {
@ -219,13 +231,15 @@ public:
return std::nullopt;
}
bool ready() {
bool
ready() {
std::lock_guard<std::mutex> lg(_task_mutex);
return !_tasks.empty() || (!_timer_tasks.empty() && std::get<0>(_timer_tasks.back()) <= std::chrono::steady_clock::now());
}
std::optional<__time_point> next() {
std::optional<__time_point>
next() {
std::lock_guard<std::mutex> lg(_task_mutex);
if (_timer_tasks.empty()) {
@ -237,7 +251,8 @@ public:
private:
template <class Function>
std::unique_ptr<_ImplBase> toRunnable(Function &&f) {
std::unique_ptr<_ImplBase>
toRunnable(Function &&f) {
return std::make_unique<_Impl<Function>>(std::forward<Function &&>(f));
}
};

View file

@ -22,9 +22,11 @@ private:
bool _continue;
public:
ThreadPool() : _continue { false } {}
ThreadPool():
_continue { false } {}
explicit ThreadPool(int threads) : _thread(threads), _continue { true } {
explicit ThreadPool(int threads):
_thread(threads), _continue { true } {
for (auto &t : _thread) {
t = std::thread(&ThreadPool::_main, this);
}
@ -38,7 +40,8 @@ public:
}
template <class Function, class... Args>
auto push(Function &&newTask, Args &&...args) {
auto
push(Function &&newTask, Args &&...args) {
std::lock_guard lg(_lock);
auto future = TaskPool::push(std::forward<Function>(newTask), std::forward<Args>(args)...);
@ -46,14 +49,16 @@ public:
return future;
}
void pushDelayed(std::pair<__time_point, __task> &&task) {
void
pushDelayed(std::pair<__time_point, __task> &&task) {
std::lock_guard lg(_lock);
TaskPool::pushDelayed(std::move(task));
}
template <class Function, class X, class Y, class... Args>
auto pushDelayed(Function &&newTask, std::chrono::duration<X, Y> duration, Args &&...args) {
auto
pushDelayed(Function &&newTask, std::chrono::duration<X, Y> duration, Args &&...args) {
std::lock_guard lg(_lock);
auto future = TaskPool::pushDelayed(std::forward<Function>(newTask), duration, std::forward<Args>(args)...);
@ -62,7 +67,8 @@ public:
return future;
}
void start(int threads) {
void
start(int threads) {
_continue = true;
_thread.resize(threads);
@ -72,21 +78,24 @@ public:
}
}
void stop() {
void
stop() {
std::lock_guard lg(_lock);
_continue = false;
_cv.notify_all();
}
void join() {
void
join() {
for (auto &t : _thread) {
t.join();
}
}
public:
void _main() {
void
_main() {
while (_continue) {
if (auto task = this->pop()) {
(*task)->run();

View file

@ -19,7 +19,8 @@ public:
using status_t = util::optional_t<T>;
template <class... Args>
void raise(Args &&...args) {
void
raise(Args &&...args) {
std::lock_guard lg { _lock };
if (!_continue) {
return;
@ -36,7 +37,8 @@ public:
}
// pop and view shoud not be used interchangeably
status_t pop() {
status_t
pop() {
std::unique_lock ul { _lock };
if (!_continue) {
@ -58,7 +60,8 @@ public:
// pop and view shoud not be used interchangeably
template <class Rep, class Period>
status_t pop(std::chrono::duration<Rep, Period> delay) {
status_t
pop(std::chrono::duration<Rep, Period> delay) {
std::unique_lock ul { _lock };
if (!_continue) {
@ -77,7 +80,8 @@ public:
}
// pop and view shoud not be used interchangeably
const status_t &view() {
const status_t &
view() {
std::unique_lock ul { _lock };
if (!_continue) {
@ -95,11 +99,13 @@ public:
return _status;
}
bool peek() {
bool
peek() {
return _continue && (bool) _status;
}
void stop() {
void
stop() {
std::lock_guard lg { _lock };
_continue = false;
@ -107,7 +113,8 @@ public:
_cv.notify_all();
}
void reset() {
void
reset() {
std::lock_guard lg { _lock };
_continue = true;
@ -115,7 +122,8 @@ public:
_status = util::false_v<status_t>;
}
[[nodiscard]] bool running() const {
[[nodiscard]] bool
running() const {
return _continue;
}
@ -132,16 +140,19 @@ class alarm_raw_t {
public:
using status_t = util::optional_t<T>;
alarm_raw_t() : _status { util::false_v<status_t> } {}
alarm_raw_t():
_status { util::false_v<status_t> } {}
void ring(const status_t &status) {
void
ring(const status_t &status) {
std::lock_guard lg(_lock);
_status = status;
_cv.notify_one();
}
void ring(status_t &&status) {
void
ring(status_t &&status) {
std::lock_guard lg(_lock);
_status = std::move(status);
@ -149,53 +160,62 @@ public:
}
template <class Rep, class Period>
auto wait_for(const std::chrono::duration<Rep, Period> &rel_time) {
auto
wait_for(const std::chrono::duration<Rep, Period> &rel_time) {
std::unique_lock ul(_lock);
return _cv.wait_for(ul, rel_time, [this]() { return (bool) status(); });
}
template <class Rep, class Period, class Pred>
auto wait_for(const std::chrono::duration<Rep, Period> &rel_time, Pred &&pred) {
auto
wait_for(const std::chrono::duration<Rep, Period> &rel_time, Pred &&pred) {
std::unique_lock ul(_lock);
return _cv.wait_for(ul, rel_time, [this, &pred]() { return (bool) status() || pred(); });
}
template <class Rep, class Period>
auto wait_until(const std::chrono::duration<Rep, Period> &rel_time) {
auto
wait_until(const std::chrono::duration<Rep, Period> &rel_time) {
std::unique_lock ul(_lock);
return _cv.wait_until(ul, rel_time, [this]() { return (bool) status(); });
}
template <class Rep, class Period, class Pred>
auto wait_until(const std::chrono::duration<Rep, Period> &rel_time, Pred &&pred) {
auto
wait_until(const std::chrono::duration<Rep, Period> &rel_time, Pred &&pred) {
std::unique_lock ul(_lock);
return _cv.wait_until(ul, rel_time, [this, &pred]() { return (bool) status() || pred(); });
}
auto wait() {
auto
wait() {
std::unique_lock ul(_lock);
_cv.wait(ul, [this]() { return (bool) status(); });
}
template <class Pred>
auto wait(Pred &&pred) {
auto
wait(Pred &&pred) {
std::unique_lock ul(_lock);
_cv.wait(ul, [this, &pred]() { return (bool) status() || pred(); });
}
const status_t &status() const {
const status_t &
status() const {
return _status;
}
status_t &status() {
status_t &
status() {
return _status;
}
void reset() {
void
reset() {
_status = status_t {};
}
@ -210,7 +230,8 @@ template<class T>
using alarm_t = std::shared_ptr<alarm_raw_t<T>>;
template <class T>
alarm_t<T> make_alarm() {
alarm_t<T>
make_alarm() {
return std::make_shared<alarm_raw_t<T>>();
}
@ -219,10 +240,12 @@ class queue_t {
public:
using status_t = util::optional_t<T>;
queue_t(std::uint32_t max_elements = 32) : _max_elements { max_elements } {}
queue_t(std::uint32_t max_elements = 32):
_max_elements { max_elements } {}
template <class... Args>
void raise(Args &&...args) {
void
raise(Args &&...args) {
std::lock_guard ul { _lock };
if (!_continue) {
@ -238,12 +261,14 @@ public:
_cv.notify_all();
}
bool peek() {
bool
peek() {
return _continue && !_queue.empty();
}
template <class Rep, class Period>
status_t pop(std::chrono::duration<Rep, Period> delay) {
status_t
pop(std::chrono::duration<Rep, Period> delay) {
std::unique_lock ul { _lock };
if (!_continue) {
@ -262,7 +287,8 @@ public:
return val;
}
status_t pop() {
status_t
pop() {
std::unique_lock ul { _lock };
if (!_continue) {
@ -283,11 +309,13 @@ public:
return val;
}
std::vector<T> &unsafe() {
std::vector<T> &
unsafe() {
return _queue;
}
void stop() {
void
stop() {
std::lock_guard lg { _lock };
_continue = false;
@ -295,7 +323,8 @@ public:
_cv.notify_all();
}
[[nodiscard]] bool running() const {
[[nodiscard]] bool
running() const {
return _continue;
}
@ -320,14 +349,18 @@ public:
struct ptr_t {
shared_t *owner;
ptr_t() : owner { nullptr } {}
explicit ptr_t(shared_t *owner) : owner { owner } {}
ptr_t():
owner { nullptr } {}
explicit ptr_t(shared_t *owner):
owner { owner } {}
ptr_t(ptr_t &&ptr) noexcept : owner { ptr.owner } {
ptr_t(ptr_t &&ptr) noexcept:
owner { ptr.owner } {
ptr.owner = nullptr;
}
ptr_t(const ptr_t &ptr) noexcept : owner { ptr.owner } {
ptr_t(const ptr_t &ptr) noexcept:
owner { ptr.owner } {
if (!owner) {
return;
}
@ -336,7 +369,8 @@ public:
tmp.owner = nullptr;
}
ptr_t &operator=(const ptr_t &ptr) noexcept {
ptr_t &
operator=(const ptr_t &ptr) noexcept {
if (!ptr.owner) {
release();
@ -346,7 +380,8 @@ public:
return *this = std::move(*ptr.owner->ref());
}
ptr_t &operator=(ptr_t &&ptr) noexcept {
ptr_t &
operator=(ptr_t &&ptr) noexcept {
if (owner) {
release();
}
@ -366,7 +401,8 @@ public:
return owner != nullptr;
}
void release() {
void
release() {
std::lock_guard lg { owner->_lock };
if (!--owner->_count) {
@ -377,18 +413,22 @@ public:
owner = nullptr;
}
element_type *get() const {
element_type *
get() const {
return reinterpret_cast<element_type *>(owner->_object_buf.data());
}
element_type *operator->() {
element_type *
operator->() {
return reinterpret_cast<element_type *>(owner->_object_buf.data());
}
};
template <class FC, class FD>
shared_t(FC &&fc, FD &&fd) : _construct { std::forward<FC>(fc) }, _destruct { std::forward<FD>(fd) } {}
[[nodiscard]] ptr_t ref() {
shared_t(FC &&fc, FD &&fd):
_construct { std::forward<FC>(fc) }, _destruct { std::forward<FD>(fd) } {}
[[nodiscard]] ptr_t
ref() {
std::lock_guard lg { _lock };
if (!_count) {
@ -414,7 +454,8 @@ private:
};
template <class T, class F_Construct, class F_Destruct>
auto make_shared(F_Construct &&fc, F_Destruct &&fd) {
auto
make_shared(F_Construct &&fc, F_Destruct &&fd) {
return shared_t<T> {
std::forward<F_Construct>(fc), std::forward<F_Destruct>(fd)
};
@ -425,12 +466,14 @@ using signal_t = event_t<bool>;
class mail_raw_t;
using mail_t = std::shared_ptr<mail_raw_t>;
void cleanup(mail_raw_t *);
void
cleanup(mail_raw_t *);
template <class T>
class post_t: public T {
public:
template <class... Args>
post_t(mail_t mail, Args &&...args) : T(std::forward<Args>(args)...), mail { std::move(mail) } {}
post_t(mail_t mail, Args &&...args):
T(std::forward<Args>(args)...), mail { std::move(mail) } {}
mail_t mail;
@ -440,7 +483,8 @@ public:
};
template <class T>
inline auto lock(const std::weak_ptr<void> &wp) {
inline auto
lock(const std::weak_ptr<void> &wp) {
return std::reinterpret_pointer_cast<typename T::element_type>(wp.lock());
}
@ -453,7 +497,8 @@ public:
using queue_t = std::shared_ptr<post_t<queue_t<T>>>;
template <class T>
event_t<T> event(const std::string_view &id) {
event_t<T>
event(const std::string_view &id) {
std::lock_guard lg { mutex };
auto it = id_to_post.find(id);
@ -468,7 +513,8 @@ public:
}
template <class T>
queue_t<T> queue(const std::string_view &id) {
queue_t<T>
queue(const std::string_view &id) {
std::lock_guard lg { mutex };
auto it = id_to_post.find(id);
@ -482,7 +528,8 @@ public:
return post;
}
void cleanup() {
void
cleanup() {
std::lock_guard lg { mutex };
for (auto it = std::begin(id_to_post); it != std::end(id_to_post); ++it) {
@ -501,7 +548,8 @@ public:
std::map<std::string, std::weak_ptr<void>, std::less<>> id_to_post;
};
inline void cleanup(mail_raw_t *mail) {
inline void
cleanup(mail_raw_t *mail) {
mail->cleanup();
}
} // namespace safe

View file

@ -35,12 +35,12 @@ struct mapping_t {
bool tcp;
};
void unmap(
void
unmap(
const urls_t &urls,
const IGDdatas &data,
std::vector<mapping_t>::const_reverse_iterator begin,
std::vector<mapping_t>::const_reverse_iterator end) {
BOOST_LOG(debug) << "Unmapping UPNP ports"sv;
for (auto it = begin; it != end; ++it) {
@ -61,8 +61,8 @@ void unmap(
class deinit_t: public platf::deinit_t {
public:
using iter_t = std::vector<mapping_t>::const_reverse_iterator;
deinit_t(urls_t &&urls, IGDdatas data, std::vector<mapping_t> &&mapping)
: urls { std::move(urls) }, data { data }, mapping { std::move(mapping) } {}
deinit_t(urls_t &&urls, IGDdatas data, std::vector<mapping_t> &&mapping):
urls { std::move(urls) }, data { data }, mapping { std::move(mapping) } {}
~deinit_t() {
BOOST_LOG(info) << "Unmapping UPNP ports..."sv;
@ -75,7 +75,8 @@ public:
std::vector<mapping_t> mapping;
};
static std::string_view status_string(int status) {
static std::string_view
status_string(int status) {
switch (status) {
case 0:
return "No IGD device found"sv;
@ -90,7 +91,8 @@ static std::string_view status_string(int status) {
return "Unknown status"sv;
}
std::unique_ptr<platf::deinit_t> start() {
std::unique_ptr<platf::deinit_t>
start() {
if (!config::sunshine.flags[config::flag::UPNP]) {
return nullptr;
}

View file

@ -4,7 +4,8 @@
#include "platform/common.h"
namespace upnp {
[[nodiscard]] std::unique_ptr<platf::deinit_t> start();
[[nodiscard]] std::unique_ptr<platf::deinit_t>
start();
}
#endif

View file

@ -40,16 +40,21 @@ struct argument_type<T(U)> {
other.el = element_type { init_val }; \
} \
\
move_t &operator=(const move_t &) = delete; \
move_t & \
operator=(const move_t &) = delete; \
\
move_t &operator=(move_t &&other) { \
move_t & \
operator=(move_t &&other) { \
std::swap(el, other.el); \
return *this; \
} \
element_type *operator->() { return &el; } \
const element_type *operator->() const { return &el; } \
element_type * \
operator->() { return &el; } \
const element_type * \
operator->() const { return &el; } \
\
inline element_type release() { \
inline element_type \
release() { \
element_type val = std::move(el); \
el = element_type { init_val }; \
return val; \
@ -146,8 +151,10 @@ template<class T>
class FailGuard {
public:
FailGuard() = delete;
FailGuard(T &&f) noexcept : _func { std::forward<T>(f) } {}
FailGuard(FailGuard &&other) noexcept : _func { std::move(other._func) } {
FailGuard(T &&f) noexcept:
_func { std::forward<T>(f) } {}
FailGuard(FailGuard &&other) noexcept:
_func { std::move(other._func) } {
this->failure = other.failure;
other.failure = false;
@ -155,8 +162,10 @@ public:
FailGuard(const FailGuard &) = delete;
FailGuard &operator=(const FailGuard &) = delete;
FailGuard &operator=(FailGuard &&other) = delete;
FailGuard &
operator=(const FailGuard &) = delete;
FailGuard &
operator=(FailGuard &&other) = delete;
~FailGuard() noexcept {
if (failure) {
@ -164,7 +173,8 @@ public:
}
}
void disable() { failure = false; }
void
disable() { failure = false; }
bool failure { true };
private:
@ -172,12 +182,14 @@ private:
};
template <class T>
[[nodiscard]] auto fail_guard(T &&f) {
[[nodiscard]] auto
fail_guard(T &&f) {
return FailGuard<T> { std::forward<T>(f) };
}
template <class T>
void append_struct(std::vector<uint8_t> &buf, const T &_struct) {
void
append_struct(std::vector<uint8_t> &buf, const T &_struct) {
constexpr size_t data_len = sizeof(_struct);
buf.reserve(data_len);
@ -219,34 +231,43 @@ public:
}
}
char *begin() { return _hex; }
char *end() { return _hex + sizeof(elem_type) * 2; }
char *
begin() { return _hex; }
char *
end() { return _hex + sizeof(elem_type) * 2; }
const char *begin() const { return _hex; }
const char *end() const { return _hex + sizeof(elem_type) * 2; }
const char *
begin() const { return _hex; }
const char *
end() const { return _hex + sizeof(elem_type) * 2; }
const char *cbegin() const { return _hex; }
const char *cend() const { return _hex + sizeof(elem_type) * 2; }
const char *
cbegin() const { return _hex; }
const char *
cend() const { return _hex + sizeof(elem_type) * 2; }
std::string to_string() const {
std::string
to_string() const {
return { begin(), end() };
}
std::string_view to_string_view() const {
std::string_view
to_string_view() const {
return { begin(), sizeof(elem_type) * 2 };
}
};
template <class T>
Hex<T> hex(const T &elem, bool rev = false) {
Hex<T>
hex(const T &elem, bool rev = false) {
return Hex<T>(elem, rev);
}
template <class It>
std::string hex_vec(It begin, It end, bool rev = false) {
std::string
hex_vec(It begin, It end, bool rev = false) {
auto str_size = 2 * std::distance(begin, end);
std::string hex;
hex.resize(str_size);
@ -268,17 +289,18 @@ std::string hex_vec(It begin, It end, bool rev = false) {
}
}
return hex;
}
template <class C>
std::string hex_vec(C &&c, bool rev = false) {
std::string
hex_vec(C &&c, bool rev = false) {
return hex_vec(std::begin(c), std::end(c), rev);
}
template <class T>
T from_hex(const std::string_view &hex, bool rev = false) {
T
from_hex(const std::string_view &hex, bool rev = false) {
std::uint8_t buf[sizeof(T)];
static char constexpr shift_bit = 'a' - 'A';
@ -329,7 +351,8 @@ T from_hex(const std::string_view &hex, bool rev = false) {
return *reinterpret_cast<T *>(buf);
}
inline std::string from_hex_vec(const std::string &hex, bool rev = false) {
inline std::string
from_hex_vec(const std::string &hex, bool rev = false) {
std::string buf;
static char constexpr shift_bit = 'a' - 'A';
@ -381,7 +404,8 @@ template<class T>
class hash {
public:
using value_type = T;
std::size_t operator()(const value_type &value) const {
std::size_t
operator()(const value_type &value) const {
const auto *p = reinterpret_cast<const char *>(&value);
return std::hash<std::string_view> {}(std::string_view { p, sizeof(value_type) });
@ -389,16 +413,19 @@ public:
};
template <class T>
auto enm(const T &val) -> const std::underlying_type_t<T> & {
auto
enm(const T &val) -> const std::underlying_type_t<T> & {
return *reinterpret_cast<const std::underlying_type_t<T> *>(&val);
}
template <class T>
auto enm(T &val) -> std::underlying_type_t<T> & {
auto
enm(T &val) -> std::underlying_type_t<T> & {
return *reinterpret_cast<std::underlying_type_t<T> *>(&val);
}
inline std::int64_t from_chars(const char *begin, const char *end) {
inline std::int64_t
from_chars(const char *begin, const char *end) {
if (begin == end) {
return 0;
}
@ -414,7 +441,8 @@ inline std::int64_t from_chars(const char *begin, const char *end) {
return *begin != '-' ? res + (std::int64_t)(*begin - '0') * mul : -res;
}
inline std::int64_t from_view(const std::string_view &number) {
inline std::int64_t
from_view(const std::string_view &number) {
return from_chars(std::begin(number), std::end(number));
}
@ -423,26 +451,32 @@ class Either : public std::variant<std::monostate, X, Y> {
public:
using std::variant<std::monostate, X, Y>::variant;
constexpr bool has_left() const {
constexpr bool
has_left() const {
return std::holds_alternative<X>(*this);
}
constexpr bool has_right() const {
constexpr bool
has_right() const {
return std::holds_alternative<Y>(*this);
}
X &left() {
X &
left() {
return std::get<X>(*this);
}
Y &right() {
Y &
right() {
return std::get<Y>(*this);
}
const X &left() const {
const X &
left() const {
return std::get<X>(*this);
}
const Y &right() const {
const Y &
right() const {
return std::get<Y>(*this);
}
};
@ -455,29 +489,36 @@ public:
using pointer = element_type *;
using deleter_type = D;
constexpr uniq_ptr() noexcept : _p { nullptr } {}
constexpr uniq_ptr(std::nullptr_t) noexcept : _p { nullptr } {}
constexpr uniq_ptr() noexcept:
_p { nullptr } {}
constexpr uniq_ptr(std::nullptr_t) noexcept:
_p { nullptr } {}
uniq_ptr(const uniq_ptr &other) noexcept = delete;
uniq_ptr &operator=(const uniq_ptr &other) noexcept = delete;
uniq_ptr &
operator=(const uniq_ptr &other) noexcept = delete;
template <class V>
uniq_ptr(V *p) noexcept : _p { p } {
uniq_ptr(V *p) noexcept:
_p { p } {
static_assert(std::is_same_v<element_type, void> || std::is_same_v<element_type, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
}
template <class V>
uniq_ptr(std::unique_ptr<V, deleter_type> &&uniq) noexcept : _p { uniq.release() } {
uniq_ptr(std::unique_ptr<V, deleter_type> &&uniq) noexcept:
_p { uniq.release() } {
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
}
template <class V>
uniq_ptr(uniq_ptr<V, deleter_type> &&other) noexcept : _p { other.release() } {
uniq_ptr(uniq_ptr<V, deleter_type> &&other) noexcept:
_p { other.release() } {
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
}
template <class V>
uniq_ptr &operator=(uniq_ptr<V, deleter_type> &&other) noexcept {
uniq_ptr &
operator=(uniq_ptr<V, deleter_type> &&other) noexcept {
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
reset(other.release());
@ -485,7 +526,8 @@ public:
}
template <class V>
uniq_ptr &operator=(std::unique_ptr<V, deleter_type> &&uniq) noexcept {
uniq_ptr &
operator=(std::unique_ptr<V, deleter_type> &&uniq) noexcept {
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
reset(uniq.release());
@ -497,7 +539,8 @@ public:
reset();
}
void reset(pointer p = pointer()) {
void
reset(pointer p = pointer()) {
if (_p) {
_deleter(_p);
}
@ -505,45 +548,56 @@ public:
_p = p;
}
pointer release() {
pointer
release() {
auto tmp = _p;
_p = nullptr;
return tmp;
}
pointer get() {
pointer
get() {
return _p;
}
const pointer get() const {
const pointer
get() const {
return _p;
}
const std::add_lvalue_reference_t<element_type> operator*() const {
const std::add_lvalue_reference_t<element_type>
operator*() const {
return *_p;
}
std::add_lvalue_reference_t<element_type> operator*() {
std::add_lvalue_reference_t<element_type>
operator*() {
return *_p;
}
const pointer operator->() const {
const pointer
operator->() const {
return _p;
}
pointer operator->() {
pointer
operator->() {
return _p;
}
pointer *operator&() const {
pointer *
operator&() const {
return &_p;
}
pointer *operator&() {
pointer *
operator&() {
return &_p;
}
deleter_type &get_deleter() {
deleter_type &
get_deleter() {
return _deleter;
}
const deleter_type &get_deleter() const {
const deleter_type &
get_deleter() const {
return _deleter;
}
@ -557,52 +611,62 @@ protected:
};
template <class T1, class D1, class T2, class D2>
bool operator==(const uniq_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
bool
operator==(const uniq_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
return x.get() == y.get();
}
template <class T1, class D1, class T2, class D2>
bool operator!=(const uniq_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
bool
operator!=(const uniq_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
return x.get() != y.get();
}
template <class T1, class D1, class T2, class D2>
bool operator==(const std::unique_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
bool
operator==(const std::unique_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
return x.get() == y.get();
}
template <class T1, class D1, class T2, class D2>
bool operator!=(const std::unique_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
bool
operator!=(const std::unique_ptr<T1, D1> &x, const uniq_ptr<T2, D2> &y) {
return x.get() != y.get();
}
template <class T1, class D1, class T2, class D2>
bool operator==(const uniq_ptr<T1, D1> &x, const std::unique_ptr<T1, D1> &y) {
bool
operator==(const uniq_ptr<T1, D1> &x, const std::unique_ptr<T1, D1> &y) {
return x.get() == y.get();
}
template <class T1, class D1, class T2, class D2>
bool operator!=(const uniq_ptr<T1, D1> &x, const std::unique_ptr<T1, D1> &y) {
bool
operator!=(const uniq_ptr<T1, D1> &x, const std::unique_ptr<T1, D1> &y) {
return x.get() != y.get();
}
template <class T, class D>
bool operator==(const uniq_ptr<T, D> &x, std::nullptr_t) {
bool
operator==(const uniq_ptr<T, D> &x, std::nullptr_t) {
return !(bool) x;
}
template <class T, class D>
bool operator!=(const uniq_ptr<T, D> &x, std::nullptr_t) {
bool
operator!=(const uniq_ptr<T, D> &x, std::nullptr_t) {
return (bool) x;
}
template <class T, class D>
bool operator==(std::nullptr_t, const uniq_ptr<T, D> &y) {
bool
operator==(std::nullptr_t, const uniq_ptr<T, D> &y) {
return !(bool) y;
}
template <class T, class D>
bool operator!=(std::nullptr_t, const uniq_ptr<T, D> &y) {
bool
operator!=(std::nullptr_t, const uniq_ptr<T, D> &y) {
return (bool) y;
}
@ -610,7 +674,8 @@ template<class P>
using shared_t = std::shared_ptr<typename P::element_type>;
template <class P, class T>
shared_t<P> make_shared(T *pointer) {
shared_t<P>
make_shared(T *pointer) {
return shared_t<P>(reinterpret_cast<typename P::pointer>(pointer), typename P::deleter_type());
}
@ -621,14 +686,19 @@ public:
using pointer = element_type *;
using reference = element_type &;
wrap_ptr() : _own_ptr { false }, _p { nullptr } {}
wrap_ptr(pointer p) : _own_ptr { false }, _p { p } {}
wrap_ptr(std::unique_ptr<element_type> &&uniq_p) : _own_ptr { true }, _p { uniq_p.release() } {}
wrap_ptr(wrap_ptr &&other) : _own_ptr { other._own_ptr }, _p { other._p } {
wrap_ptr():
_own_ptr { false }, _p { nullptr } {}
wrap_ptr(pointer p):
_own_ptr { false }, _p { p } {}
wrap_ptr(std::unique_ptr<element_type> &&uniq_p):
_own_ptr { true }, _p { uniq_p.release() } {}
wrap_ptr(wrap_ptr &&other):
_own_ptr { other._own_ptr }, _p { other._p } {
other._own_ptr = false;
}
wrap_ptr &operator=(wrap_ptr &&other) noexcept {
wrap_ptr &
operator=(wrap_ptr &&other) noexcept {
if (_own_ptr) {
delete _p;
}
@ -642,7 +712,8 @@ public:
}
template <class V>
wrap_ptr &operator=(std::unique_ptr<V> &&uniq_ptr) {
wrap_ptr &
operator=(std::unique_ptr<V> &&uniq_ptr) {
static_assert(std::is_base_of_v<element_type, V>, "element_type must be base class of V");
_own_ptr = true;
_p = uniq_ptr.release();
@ -650,7 +721,8 @@ public:
return *this;
}
wrap_ptr &operator=(pointer p) {
wrap_ptr &
operator=(pointer p) {
if (_own_ptr) {
delete _p;
}
@ -669,16 +741,20 @@ public:
_own_ptr = false;
}
const reference operator*() const {
const reference
operator*() const {
return *_p;
}
reference operator*() {
reference
operator*() {
return *_p;
}
const pointer operator->() const {
const pointer
operator->() const {
return _p;
}
pointer operator->() {
pointer
operator->() {
return _p;
}
@ -723,54 +799,68 @@ using optional_t = either_t<
template <class T>
class buffer_t {
public:
buffer_t() : _els { 0 } {};
buffer_t(buffer_t &&o) noexcept : _els { o._els }, _buf { std::move(o._buf) } {
buffer_t():
_els { 0 } {};
buffer_t(buffer_t &&o) noexcept:
_els { o._els }, _buf { std::move(o._buf) } {
o._els = 0;
}
buffer_t(const buffer_t &o) : _els { o._els }, _buf { std::make_unique<T[]>(_els) } {
buffer_t(const buffer_t &o):
_els { o._els }, _buf { std::make_unique<T[]>(_els) } {
std::copy(o.begin(), o.end(), begin());
}
buffer_t &operator=(buffer_t &&o) noexcept {
buffer_t &
operator=(buffer_t &&o) noexcept {
std::swap(_els, o._els);
std::swap(_buf, o._buf);
return *this;
};
explicit buffer_t(size_t elements) : _els { elements }, _buf { std::make_unique<T[]>(elements) } {}
explicit buffer_t(size_t elements, const T &t) : _els { elements }, _buf { std::make_unique<T[]>(elements) } {
explicit buffer_t(size_t elements):
_els { elements }, _buf { std::make_unique<T[]>(elements) } {}
explicit buffer_t(size_t elements, const T &t):
_els { elements }, _buf { std::make_unique<T[]>(elements) } {
std::fill_n(_buf.get(), elements, t);
}
T &operator[](size_t el) {
T &
operator[](size_t el) {
return _buf[el];
}
const T &operator[](size_t el) const {
const T &
operator[](size_t el) const {
return _buf[el];
}
size_t size() const {
size_t
size() const {
return _els;
}
void fake_resize(std::size_t els) {
void
fake_resize(std::size_t els) {
_els = els;
}
T *begin() {
T *
begin() {
return _buf.get();
}
const T *begin() const {
const T *
begin() const {
return _buf.get();
}
T *end() {
T *
end() {
return _buf.get() + _els;
}
const T *end() const {
const T *
end() const {
return _buf.get() + _els;
}
@ -780,7 +870,8 @@ private:
};
template <class T>
T either(std::optional<T> &&l, T &&r) {
T
either(std::optional<T> &&l, T &&r) {
if (l) {
return std::move(*l);
}
@ -797,7 +888,8 @@ template<class T, class ReturnType, typename Function<ReturnType, T>::type funct
struct Destroy {
typedef T pointer;
void operator()(pointer p) {
void
operator()(pointer p) {
function(p);
}
};
@ -810,12 +902,14 @@ template<class T, class ReturnType, typename Function<ReturnType, T *>::type fun
using safe_ptr_v2 = uniq_ptr<T, Destroy<T *, ReturnType, function>>;
template <class T>
void c_free(T *p) {
void
c_free(T *p) {
free(p);
}
template <class T, class ReturnType, ReturnType (**function)(T *)>
void dynamic(T *p) {
void
dynamic(T *p) {
(*function)(p);
}
@ -829,12 +923,14 @@ template<class T>
using c_ptr = safe_ptr<T, c_free<T>>;
template <class It>
std::string_view view(It begin, It end) {
std::string_view
view(It begin, It end) {
return std::string_view { (const char *) begin, (std::size_t)(end - begin) };
}
template <class T>
std::string_view view(const T &data) {
std::string_view
view(const T &data) {
return std::string_view((const char *) &data, sizeof(T));
}
@ -872,7 +968,8 @@ struct endian_helper {};
template <class T>
struct endian_helper<T, std::enable_if_t<
!(instantiation_of_v<std::optional, T>)>> {
static inline T big(T x) {
static inline T
big(T x) {
if constexpr (endianness<T>::little) {
uint8_t *data = reinterpret_cast<uint8_t *>(&x);
@ -882,7 +979,8 @@ struct endian_helper<T, std::enable_if_t<
return x;
}
static inline T little(T x) {
static inline T
little(T x) {
if constexpr (endianness<T>::big) {
uint8_t *data = reinterpret_cast<uint8_t *>(&x);
@ -896,7 +994,8 @@ struct endian_helper<T, std::enable_if_t<
template <class T>
struct endian_helper<T, std::enable_if_t<
instantiation_of_v<std::optional, T>>> {
static inline T little(T x) {
static inline T
little(T x) {
if (!x) return x;
if constexpr (endianness<T>::big) {
@ -908,8 +1007,8 @@ struct endian_helper<T, std::enable_if_t<
return x;
}
static inline T big(T x) {
static inline T
big(T x) {
if (!x) return x;
if constexpr (endianness<T>::little) {
@ -923,10 +1022,12 @@ struct endian_helper<T, std::enable_if_t<
};
template <class T>
inline auto little(T x) { return endian_helper<T>::little(x); }
inline auto
little(T x) { return endian_helper<T>::little(x); }
template <class T>
inline auto big(T x) { return endian_helper<T>::big(x); }
inline auto
big(T x) { return endian_helper<T>::big(x); }
} // namespace endian
} // namespace util
#endif

View file

@ -12,7 +12,8 @@ union uuid_t {
std::uint32_t b32[4];
std::uint64_t b64[2];
static uuid_t generate(std::default_random_engine &engine) {
static uuid_t
generate(std::default_random_engine &engine) {
std::uniform_int_distribution<std::uint8_t> dist(0, std::numeric_limits<std::uint8_t>::max());
uuid_t buf;
@ -26,7 +27,8 @@ union uuid_t {
return buf;
}
static uuid_t generate() {
static uuid_t
generate() {
std::random_device r;
std::default_random_engine engine { r() };
@ -34,7 +36,8 @@ union uuid_t {
return generate(engine);
}
[[nodiscard]] std::string string() const {
[[nodiscard]] std::string
string() const {
std::string result;
result.reserve(sizeof(uuid_t) * 2 + 4);
@ -61,15 +64,18 @@ union uuid_t {
return result;
}
constexpr bool operator==(const uuid_t &other) const {
constexpr bool
operator==(const uuid_t &other) const {
return b64[0] == other.b64[0] && b64[1] == other.b64[1];
}
constexpr bool operator<(const uuid_t &other) const {
constexpr bool
operator<(const uuid_t &other) const {
return (b64[0] < other.b64[0] || (b64[0] == other.b64[0] && b64[1] < other.b64[1]));
}
constexpr bool operator>(const uuid_t &other) const {
constexpr bool
operator>(const uuid_t &other) const {
return (b64[0] > other.b64[0] || (b64[0] == other.b64[0] && b64[1] > other.b64[1]));
}
};

View file

@ -30,15 +30,18 @@ namespace video {
constexpr auto hevc_nalu = "\000\000\000\001("sv;
constexpr auto h264_nalu = "\000\000\000\001e"sv;
void free_ctx(AVCodecContext *ctx) {
void
free_ctx(AVCodecContext *ctx) {
avcodec_free_context(&ctx);
}
void free_frame(AVFrame *frame) {
void
free_frame(AVFrame *frame) {
av_frame_free(&frame);
}
void free_buffer(AVBufferRef *ref) {
void
free_buffer(AVBufferRef *ref) {
av_buffer_unref(&ref);
}
@ -78,19 +81,25 @@ enum class profile_hevc_e : int {
};
} // namespace qsv
platf::mem_type_e
map_base_dev_type(AVHWDeviceType type);
platf::pix_fmt_e
map_pix_fmt(AVPixelFormat fmt);
platf::mem_type_e map_base_dev_type(AVHWDeviceType type);
platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt);
util::Either<buffer_t, int>
dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int>
vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int>
cuda_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
int hwframe_ctx(ctx_t &ctx, platf::hwdevice_t *hwdevice, buffer_t &hwdevice_ctx, AVPixelFormat format);
int
hwframe_ctx(ctx_t &ctx, platf::hwdevice_t *hwdevice, buffer_t &hwdevice_ctx, AVPixelFormat format);
class swdevice_t: public platf::hwdevice_t {
public:
int convert(platf::img_t &img) override {
int
convert(platf::img_t &img) override {
av_frame_make_writable(sw_frame.get());
const int linesizes[2] {
@ -131,7 +140,8 @@ public:
return 0;
}
int set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
int
set_frame(AVFrame *frame, AVBufferRef *hw_frames_ctx) {
this->frame = frame;
// If it's a hwframe, allocate buffers for hardware
@ -147,7 +157,8 @@ public:
return 0;
}
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
void
set_colorspace(std::uint32_t colorspace, std::uint32_t color_range) override {
sws_setColorspaceDetails(sws.get(),
sws_getCoefficients(SWS_CS_DEFAULT), 0,
sws_getCoefficients(colorspace), color_range - 1,
@ -157,7 +168,8 @@ public:
/**
* When preserving aspect ratio, ensure that padding is black
*/
int prefill() {
int
prefill() {
auto frame = sw_frame ? sw_frame.get() : this->frame;
auto width = frame->width;
auto height = frame->height;
@ -195,7 +207,8 @@ public:
return 0;
}
int init(int in_width, int in_height, AVFrame *frame, AVPixelFormat format, bool hardware) {
int
init(int in_width, int in_height, AVFrame *frame, AVPixelFormat format, bool hardware) {
// If the device used is hardware, yet the image resides on main memory
if (hardware) {
sw_frame.reset(av_frame_alloc());
@ -273,7 +286,8 @@ struct encoder_t {
MAX_FLAGS
};
static std::string_view from_flag(flag_e flag) {
static std::string_view
from_flag(flag_e flag) {
#define _CONVERT(x) \
case flag_e::x: \
return #x##sv
@ -300,7 +314,8 @@ struct encoder_t {
std::string name;
std::variant<int, int *, std::optional<int> *, std::string, std::string *> value;
option_t(std::string &&name, decltype(value) &&value) : name { std::move(name) }, value { std::move(value) } {}
option_t(std::string &&name, decltype(value) &&value):
name { std::move(name) }, value { std::move(value) } {}
};
AVHWDeviceType base_dev_type, derived_dev_type;
@ -317,11 +332,13 @@ struct encoder_t {
std::string name;
std::bitset<MAX_FLAGS> capabilities;
bool operator[](flag_e flag) const {
bool
operator[](flag_e flag) const {
return capabilities[(std::size_t) flag];
}
std::bitset<MAX_FLAGS>::reference operator[](flag_e flag) {
std::bitset<MAX_FLAGS>::reference
operator[](flag_e flag) {
return capabilities[(std::size_t) flag];
}
} hevc, h264;
@ -334,7 +351,8 @@ struct encoder_t {
class session_t {
public:
session_t() = default;
session_t(ctx_t &&ctx, std::shared_ptr<platf::hwdevice_t> &&device, int inject) : ctx { std::move(ctx) }, device { std::move(device) }, inject { inject } {}
session_t(ctx_t &&ctx, std::shared_ptr<platf::hwdevice_t> &&device, int inject):
ctx { std::move(ctx) }, device { std::move(device) }, inject { inject } {}
session_t(session_t &&other) noexcept = default;
~session_t() {
@ -344,7 +362,8 @@ public:
}
// Ensure objects are destroyed in the correct order
session_t &operator=(session_t &&other) {
session_t &
operator=(session_t &&other) {
device = std::move(other.device);
ctx = std::move(other.ctx);
replacements = std::move(other.replacements);
@ -409,10 +428,14 @@ struct capture_thread_sync_ctx_t {
encode_session_ctx_queue_t encode_session_ctx_queue { 30 };
};
int start_capture_sync(capture_thread_sync_ctx_t &ctx);
void end_capture_sync(capture_thread_sync_ctx_t &ctx);
int start_capture_async(capture_thread_async_ctx_t &ctx);
void end_capture_async(capture_thread_async_ctx_t &ctx);
int
start_capture_sync(capture_thread_sync_ctx_t &ctx);
void
end_capture_sync(capture_thread_sync_ctx_t &ctx);
int
start_capture_async(capture_thread_async_ctx_t &ctx);
void
end_capture_async(capture_thread_async_ctx_t &ctx);
// Keep a reference counter to ensure the capture thread only runs when other threads have a reference to the capture thread
auto capture_thread_async = safe::make_shared<capture_thread_async_ctx_t>(start_capture_async, end_capture_async);
@ -704,7 +727,8 @@ static std::vector<encoder_t> encoders {
software
};
void reset_display(std::shared_ptr<platf::display_t> &disp, AVHWDeviceType type, const std::string &display_name, const config_t &config) {
void
reset_display(std::shared_ptr<platf::display_t> &disp, AVHWDeviceType type, const std::string &display_name, const config_t &config) {
// We try this twice, in case we still get an error on reinitialization
for (int x = 0; x < 2; ++x) {
disp.reset();
@ -718,7 +742,8 @@ void reset_display(std::shared_ptr<platf::display_t> &disp, AVHWDeviceType type,
}
}
void captureThread(
void
captureThread(
std::shared_ptr<safe::queue_t<capture_ctx_t>> capture_ctx_queue,
sync_util::sync_t<std::weak_ptr<platf::display_t>> &display_wp,
safe::signal_t &reinit_event,
@ -822,7 +847,6 @@ void captureThread(
},
*round_robin++, &display_cursor);
if (artificial_reinit && status != platf::capture_e::error) {
status = platf::capture_e::reinit;
@ -898,7 +922,8 @@ void captureThread(
}
}
int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::mail_raw_t::queue_t<packet_t> &packets, void *channel_data) {
int
encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::mail_raw_t::queue_t<packet_t> &packets, void *channel_data) {
frame->pts = frame_nr;
auto &ctx = session.ctx;
@ -946,7 +971,6 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::m
session.inject = 0;
session.replacements.emplace_back(
std::string_view((char *) std::begin(sps.old), sps.old.size()),
std::string_view((char *) std::begin(sps._new), sps._new.size()));
@ -960,7 +984,8 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::m
return 0;
}
std::optional<session_t> make_session(platf::display_t *disp, const encoder_t &encoder, const config_t &config, int width, int height, std::shared_ptr<platf::hwdevice_t> &&hwdevice) {
std::optional<session_t>
make_session(platf::display_t *disp, const encoder_t &encoder, const config_t &config, int width, int height, std::shared_ptr<platf::hwdevice_t> &&hwdevice) {
bool hardware = encoder.base_dev_type != AV_HWDEVICE_TYPE_NONE;
auto &video_format = config.videoFormat == 0 ? encoder.h264 : encoder.hevc;
@ -1270,7 +1295,8 @@ std::optional<session_t> make_session(platf::display_t *disp, const encoder_t &e
return std::make_optional(std::move(session));
}
void encode_run(
void
encode_run(
int &frame_nr, // Store progress of the frame number
safe::mail_t mail,
img_event_t images,
@ -1280,7 +1306,6 @@ void encode_run(
safe::signal_t &reinit_event,
const encoder_t &encoder,
void *channel_data) {
auto session = make_session(disp.get(), encoder, config, disp->width, disp->height, std::move(hwdevice));
if (!session) {
return;
@ -1334,7 +1359,8 @@ void encode_run(
}
}
input::touch_port_t make_port(platf::display_t *display, const config_t &config) {
input::touch_port_t
make_port(platf::display_t *display, const config_t &config) {
float wd = display->width;
float hd = display->height;
@ -1362,7 +1388,8 @@ input::touch_port_t make_port(platf::display_t *display, const config_t &config)
};
}
std::optional<sync_session_t> make_synced_session(platf::display_t *disp, const encoder_t &encoder, platf::img_t &img, sync_session_ctx_t &ctx) {
std::optional<sync_session_t>
make_synced_session(platf::display_t *disp, const encoder_t &encoder, platf::img_t &img, sync_session_ctx_t &ctx) {
sync_session_t encode_session;
encode_session.ctx = &ctx;
@ -1394,10 +1421,10 @@ std::optional<sync_session_t> make_synced_session(platf::display_t *disp, const
return std::move(encode_session);
}
encode_e encode_run_sync(
encode_e
encode_run_sync(
std::vector<std::unique_ptr<sync_session_ctx_t>> &synced_session_ctxs,
encode_session_ctx_queue_t &encode_session_ctx_queue) {
const auto &encoder = encoders.front();
auto display_names = platf::display_names(map_base_dev_type(encoder.base_dev_type));
int display_p = 0;
@ -1543,7 +1570,8 @@ encode_e encode_run_sync(
return encode_e::ok;
}
void captureThreadSync() {
void
captureThreadSync() {
auto ref = capture_thread_sync.ref();
std::vector<std::unique_ptr<sync_session_ctx_t>> synced_session_ctxs;
@ -1569,11 +1597,11 @@ void captureThreadSync() {
while (encode_run_sync(synced_session_ctxs, ctx) == encode_e::reinit) {}
}
void capture_async(
void
capture_async(
safe::mail_t mail,
config_t &config,
void *channel_data) {
auto shutdown_event = mail->event<bool>(mail::shutdown);
auto images = std::make_shared<img_event_t::element_type>();
@ -1646,11 +1674,11 @@ void capture_async(
}
}
void capture(
void
capture(
safe::mail_t mail,
config_t config,
void *channel_data) {
auto idr_events = mail->event<bool>(mail::idr);
idr_events->raise(true);
@ -1682,7 +1710,8 @@ enum validate_flag_e {
NALU_PREFIX_5b = 0x02,
};
int validate_config(std::shared_ptr<platf::display_t> &disp, const encoder_t &encoder, const config_t &config) {
int
validate_config(std::shared_ptr<platf::display_t> &disp, const encoder_t &encoder, const config_t &config) {
reset_display(disp, encoder.base_dev_type, config::video.output_name, config);
if (!disp) {
return -1;
@ -1740,7 +1769,8 @@ int validate_config(std::shared_ptr<platf::display_t> &disp, const encoder_t &en
return flag;
}
bool validate_encoder(encoder_t &encoder) {
bool
validate_encoder(encoder_t &encoder) {
std::shared_ptr<platf::display_t> disp;
BOOST_LOG(info) << "Trying encoder ["sv << encoder.name << ']';
@ -1868,7 +1898,8 @@ retry:
return true;
}
int init() {
int
init() {
bool encoder_found = false;
if (!config::video.encoder.empty()) {
// If there is a specific encoder specified, use it if it passes validation
@ -1985,7 +2016,8 @@ int init() {
return 0;
}
int hwframe_ctx(ctx_t &ctx, platf::hwdevice_t *hwdevice, buffer_t &hwdevice_ctx, AVPixelFormat format) {
int
hwframe_ctx(ctx_t &ctx, platf::hwdevice_t *hwdevice, buffer_t &hwdevice_ctx, AVPixelFormat format) {
buffer_t frame_ref { av_hwframe_ctx_alloc(hwdevice_ctx.get()) };
auto frame_ctx = (AVHWFramesContext *) frame_ref->data;
@ -2010,7 +2042,8 @@ int hwframe_ctx(ctx_t &ctx, platf::hwdevice_t *hwdevice, buffer_t &hwdevice_ctx,
// Linux only declaration
typedef int (*vaapi_make_hwdevice_ctx_fn)(platf::hwdevice_t *base, AVBufferRef **hw_device_buf);
util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *base) {
util::Either<buffer_t, int>
vaapi_make_hwdevice_ctx(platf::hwdevice_t *base) {
buffer_t hw_device_buf;
// If an egl hwdevice
@ -2034,7 +2067,8 @@ util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *base) {
return hw_device_buf;
}
util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *base) {
util::Either<buffer_t, int>
cuda_make_hwdevice_ctx(platf::hwdevice_t *base) {
buffer_t hw_device_buf;
auto status = av_hwdevice_ctx_create(&hw_device_buf, AV_HWDEVICE_TYPE_CUDA, nullptr, nullptr, 1 /* AV_CUDA_USE_PRIMARY_CONTEXT */);
@ -2050,10 +2084,12 @@ util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *base) {
#ifdef _WIN32
}
void do_nothing(void *) {}
void
do_nothing(void *) {}
namespace video {
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx) {
util::Either<buffer_t, int>
dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx) {
buffer_t ctx_buf { av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_D3D11VA) };
auto ctx = (AVD3D11VADeviceContext *) ((AVHWDeviceContext *) ctx_buf->data)->hwctx;
@ -2080,7 +2116,8 @@ util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_c
}
#endif
int start_capture_async(capture_thread_async_ctx_t &capture_thread_ctx) {
int
start_capture_async(capture_thread_async_ctx_t &capture_thread_ctx) {
capture_thread_ctx.encoder_p = &encoders.front();
capture_thread_ctx.reinit_event.reset();
@ -2096,19 +2133,23 @@ int start_capture_async(capture_thread_async_ctx_t &capture_thread_ctx) {
return 0;
}
void end_capture_async(capture_thread_async_ctx_t &capture_thread_ctx) {
void
end_capture_async(capture_thread_async_ctx_t &capture_thread_ctx) {
capture_thread_ctx.capture_ctx_queue->stop();
capture_thread_ctx.capture_thread.join();
}
int start_capture_sync(capture_thread_sync_ctx_t &ctx) {
int
start_capture_sync(capture_thread_sync_ctx_t &ctx) {
std::thread { &captureThreadSync }.detach();
return 0;
}
void end_capture_sync(capture_thread_sync_ctx_t &ctx) {}
void
end_capture_sync(capture_thread_sync_ctx_t &ctx) {}
platf::mem_type_e map_base_dev_type(AVHWDeviceType type) {
platf::mem_type_e
map_base_dev_type(AVHWDeviceType type) {
switch (type) {
case AV_HWDEVICE_TYPE_D3D11VA:
return platf::mem_type_e::dxgi;
@ -2125,7 +2166,8 @@ platf::mem_type_e map_base_dev_type(AVHWDeviceType type) {
return platf::mem_type_e::unknown;
}
platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt) {
platf::pix_fmt_e
map_pix_fmt(AVPixelFormat fmt) {
switch (fmt) {
case AV_PIX_FMT_YUV420P10:
return platf::pix_fmt_e::yuv420p10;
@ -2142,7 +2184,8 @@ platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt) {
return platf::pix_fmt_e::unknown;
}
color_t make_color_matrix(float Cr, float Cb, const float2 &range_Y, const float2 &range_UV) {
color_t
make_color_matrix(float Cr, float Cb, const float2 &range_Y, const float2 &range_UV) {
float Cg = 1.0f - Cr - Cb;
float Cr_i = 1.0f - Cr;

View file

@ -15,16 +15,19 @@ struct AVPacket;
namespace video {
struct packet_raw_t {
void init_packet() {
void
init_packet() {
this->av_packet = av_packet_alloc();
}
template <class P>
explicit packet_raw_t(P *user_data) : channel_data { user_data } {
explicit packet_raw_t(P *user_data):
channel_data { user_data } {
init_packet();
}
explicit packet_raw_t(std::nullptr_t) : channel_data { nullptr } {
explicit packet_raw_t(std::nullptr_t):
channel_data { nullptr } {
init_packet();
}
@ -38,7 +41,8 @@ struct packet_raw_t {
KITTY_DEFAULT_CONSTR_MOVE(replace_t)
replace_t(std::string_view old, std::string_view _new) noexcept : old { std::move(old) }, _new { std::move(_new) } {}
replace_t(std::string_view old, std::string_view _new) noexcept:
old { std::move(old) }, _new { std::move(_new) } {}
};
AVPacket *av_packet;
@ -49,8 +53,10 @@ struct packet_raw_t {
using packet_t = std::unique_ptr<packet_raw_t>;
struct hdr_info_raw_t {
explicit hdr_info_raw_t(bool enabled) : enabled { enabled }, metadata {} {};
explicit hdr_info_raw_t(bool enabled, const SS_HDR_METADATA &metadata) : enabled { enabled }, metadata { metadata } {};
explicit hdr_info_raw_t(bool enabled):
enabled { enabled }, metadata {} {};
explicit hdr_info_raw_t(bool enabled, const SS_HDR_METADATA &metadata):
enabled { enabled }, metadata { metadata } {};
bool enabled;
SS_HDR_METADATA metadata;
@ -84,12 +90,14 @@ struct alignas(16) color_t {
extern color_t colors[6];
void capture(
void
capture(
safe::mail_t mail,
config_t config,
void *channel_data);
int init();
int
init();
} // namespace video
#endif // SUNSHINE_VIDEO_H

@ -1 +1 @@
Subproject commit 726404ef5590ea4bfcc7d9fa40cadcb2638a5b82
Subproject commit 9e842ba1c3a6efbb90d9b7e9346a55b1a3d10494

@ -1 +1 @@
Subproject commit 4a29f4eeaf7d207f171b5afb06327a2b6912b14c
Subproject commit 22034b2bafd873308a1857da749eabe9b537b33b

@ -1 +1 @@
Subproject commit 05eff5066370a9c223b56ae8c5d0684e0d06a0fe
Subproject commit d8f29a064caabdeb78f263a5017a5dbdaa454eb6

@ -1 +1 @@
Subproject commit 645dcc56665a5a3c4f7a5284a1e42abc76cb5278
Subproject commit 5876c4b765670deaeb6927c1785085bbf1a98b96

@ -1 +1 @@
Subproject commit 759f5fc2165ef070bd300edcc691c48ccb8f84f8
Subproject commit d75ce5ffeef371cedb6fbbb23ac5603e34c2994b

@ -1 +1 @@
Subproject commit b05f94a92ee0a3de4742f6b4897556b6b84f5dd5
Subproject commit c4d6360a59d149b1ea097a5658ab1193e20db643

View file

@ -148,7 +148,6 @@ typedef EGLNativeDisplayType NativeDisplayType;
typedef EGLNativePixmapType NativePixmapType;
typedef EGLNativeWindowType NativeWindowType;
/* Define EGLint. This must be a signed integral type large enough to contain
* all legal attribute names and values passed into and out of EGL, whether
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
@ -158,7 +157,6 @@ typedef EGLNativeWindowType NativeWindowType;
*/
typedef khronos_int32_t EGLint;
/* C++ / C typecast macros for special EGL handle values */
#if defined(__cplusplus)
#define EGL_CAST(type, value) (static_cast<type>(value))

View file

@ -142,7 +142,6 @@
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
@ -221,7 +220,6 @@ typedef uint64_t khronos_uint64_t;
#endif
/*
* Types that are (so far) the same on all platforms
*/

View file

@ -28,7 +28,6 @@
#ifndef GLAD_EGL_H_
#define GLAD_EGL_H_
#define GLAD_EGL
#define GLAD_OPTION_EGL_LOADER
@ -316,12 +315,10 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define EGL_WIDTH 0x3057
#define EGL_WINDOW_BIT 0x0004
#include <KHR/khrplatform.h>
#include <EGL/eglplatform.h>
struct AHardwareBuffer;
struct wl_buffer;
@ -330,7 +327,6 @@ struct wl_display;
struct wl_resource;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
@ -410,7 +406,6 @@ typedef void(GLAD_API_PTR *EGLDEBUGPROCKHR)(EGLenum error, const char *command,
#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
#define EGL_VERSION_1_0 1
GLAD_API_CALL int GLAD_EGL_VERSION_1_0;
#define EGL_VERSION_1_1 1
@ -424,7 +419,6 @@ GLAD_API_CALL int GLAD_EGL_VERSION_1_4;
#define EGL_VERSION_1_5 1
GLAD_API_CALL int GLAD_EGL_VERSION_1_5;
typedef EGLBoolean(GLAD_API_PTR *PFNEGLBINDAPIPROC)(EGLenum api);
typedef EGLBoolean(GLAD_API_PTR *PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean(GLAD_API_PTR *PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
@ -567,15 +561,18 @@ GLAD_API_CALL PFNEGLWAITNATIVEPROC glad_eglWaitNative;
GLAD_API_CALL PFNEGLWAITSYNCPROC glad_eglWaitSync;
#define eglWaitSync glad_eglWaitSync
GLAD_API_CALL int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoadEGL(EGLDisplay display, GLADloadfunc load);
GLAD_API_CALL int
gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int
gladLoadEGL(EGLDisplay display, GLADloadfunc load);
#ifdef GLAD_EGL
GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display);
GLAD_API_CALL int
gladLoaderLoadEGL(EGLDisplay display);
GLAD_API_CALL void gladLoaderUnloadEGL(void);
GLAD_API_CALL void
gladLoaderUnloadEGL(void);
#endif
#ifdef __cplusplus

View file

@ -1983,7 +1983,6 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_ZOOM_X 0x0D16
#define GL_ZOOM_Y 0x0D17
#include <KHR/khrplatform.h>
typedef unsigned int GLenum;
@ -2090,7 +2089,6 @@ typedef GLintptr GLvdpauSurfaceNV;
typedef void(GLAD_API_PTR *GLVULKANPROCNV)(void);
#define GL_VERSION_1_0 1
#define GL_VERSION_1_1 1
#define GL_VERSION_1_2 1
@ -4235,15 +4233,17 @@ typedef struct GladGLContext {
PFNGLWINDOWPOS3SVPROC WindowPos3sv;
} GladGLContext;
GLAD_API_CALL int gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoadGLContext(GladGLContext *context, GLADloadfunc load);
GLAD_API_CALL int
gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int
gladLoadGLContext(GladGLContext *context, GLADloadfunc load);
#ifdef GLAD_GL
GLAD_API_CALL int gladLoaderLoadGLContext(GladGLContext *context);
GLAD_API_CALL void gladLoaderUnloadGL(void);
GLAD_API_CALL int
gladLoaderLoadGLContext(GladGLContext *context);
GLAD_API_CALL void
gladLoaderUnloadGL(void);
#endif

@ -1 +1 @@
Subproject commit e439318cf782e30066d430f27a1365e013a5ab94
Subproject commit 014c9df8ee7a36e5bf85aa619062a2d4b95ec8f6

@ -1 +1 @@
Subproject commit c9426a6a71c4162e65dde8c0c71a25f1dbca46ba
Subproject commit d3cb8131d12832898af31c4f2484ec1bd6bed0f4

2
third-party/nanors vendored

@ -1 +1 @@
Subproject commit e9e242e98e27037830490b2a752895ca68f75f8b
Subproject commit 395e5ada44dd8d5974eaf6bb6b17f23406e3ca72

View file

@ -1525,7 +1525,8 @@ typedef struct _NVFBC_TOGL_GRAB_FRAME_PARAMS {
* A NULL terminated error message, or an empty string. Its maximum length
* is NVFBC_ERROR_STR_LEN.
*/
const char *NVFBCAPI NvFBCGetLastErrorStr(const NVFBC_SESSION_HANDLE sessionHandle);
const char *NVFBCAPI
NvFBCGetLastErrorStr(const NVFBC_SESSION_HANDLE sessionHandle);
/*!
* \brief Allocates a new handle for an NvFBC client.
@ -1551,7 +1552,8 @@ const char *NVFBCAPI NvFBCGetLastErrorStr(const NVFBC_SESSION_HANDLE sessionHand
* ::NVFBC_ERR_GL
*
*/
NVFBCSTATUS NVFBCAPI NvFBCCreateHandle(NVFBC_SESSION_HANDLE *pSessionHandle, NVFBC_CREATE_HANDLE_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCCreateHandle(NVFBC_SESSION_HANDLE *pSessionHandle, NVFBC_CREATE_HANDLE_PARAMS *pParams);
/*!
* \brief Destroys the handle of an NvFBC client.
@ -1577,7 +1579,8 @@ NVFBCSTATUS NVFBCAPI NvFBCCreateHandle(NVFBC_SESSION_HANDLE *pSessionHandle, NVF
* ::NVFBC_ERR_CONTEXT \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCDestroyHandle(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_HANDLE_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCDestroyHandle(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_HANDLE_PARAMS *pParams);
/*!
* \brief Gets the current status of the display driver.
@ -1596,7 +1599,8 @@ NVFBCSTATUS NVFBCAPI NvFBCDestroyHandle(const NVFBC_SESSION_HANDLE sessionHandle
* ::NVFBC_ERR_INTERNAL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCGetStatus(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_GET_STATUS_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCGetStatus(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_GET_STATUS_PARAMS *pParams);
/*!
* \brief Binds the FBC context to the calling thread.
@ -1630,7 +1634,8 @@ NVFBCSTATUS NVFBCAPI NvFBCGetStatus(const NVFBC_SESSION_HANDLE sessionHandle, NV
* ::NVFBC_ERR_INTERNAL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCBindContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_BIND_CONTEXT_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCBindContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_BIND_CONTEXT_PARAMS *pParams);
/*!
* \brief Releases the FBC context from the calling thread.
@ -1651,7 +1656,8 @@ NVFBCSTATUS NVFBCAPI NvFBCBindContext(const NVFBC_SESSION_HANDLE sessionHandle,
* ::NVFBC_ERR_INTERNAL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCReleaseContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_RELEASE_CONTEXT_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCReleaseContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_RELEASE_CONTEXT_PARAMS *pParams);
/*!
* \brief Creates a capture session for an FBC client.
@ -1686,7 +1692,8 @@ NVFBCSTATUS NVFBCAPI NvFBCReleaseContext(const NVFBC_SESSION_HANDLE sessionHandl
* ::NVFBC_ERR_MUST_RECREATE \n
* ::NVFBC_ERR_INTERNAL
*/
NVFBCSTATUS NVFBCAPI NvFBCCreateCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_CREATE_CAPTURE_SESSION_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCCreateCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_CREATE_CAPTURE_SESSION_PARAMS *pParams);
/*!
* \brief Destroys a capture session for an FBC client.
@ -1710,7 +1717,8 @@ NVFBCSTATUS NVFBCAPI NvFBCCreateCaptureSession(const NVFBC_SESSION_HANDLE sessio
* ::NVFBC_ERR_INTERNAL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCDestroyCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_CAPTURE_SESSION_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCDestroyCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_CAPTURE_SESSION_PARAMS *pParams);
/*!
* \brief Sets up a capture to system memory session.
@ -1742,7 +1750,8 @@ NVFBCSTATUS NVFBCAPI NvFBCDestroyCaptureSession(const NVFBC_SESSION_HANDLE sessi
* ::NVFBC_ERR_OUT_OF_MEMORY \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCToSysSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_SETUP_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToSysSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_SETUP_PARAMS *pParams);
/*!
* \brief Captures a frame to a buffer in system memory.
@ -1782,7 +1791,8 @@ NVFBCSTATUS NVFBCAPI NvFBCToSysSetUp(const NVFBC_SESSION_HANDLE sessionHandle, N
* \see NvFBCCreateCaptureSession \n
* \see NvFBCToSysSetUp
*/
NVFBCSTATUS NVFBCAPI NvFBCToSysGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_GRAB_FRAME_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToSysGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_GRAB_FRAME_PARAMS *pParams);
/*!
* \brief Sets up a capture to video memory session.
@ -1809,7 +1819,8 @@ NVFBCSTATUS NVFBCAPI NvFBCToSysGrabFrame(const NVFBC_SESSION_HANDLE sessionHandl
* ::NVFBC_ERR_GL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCToCudaSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_SETUP_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToCudaSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_SETUP_PARAMS *pParams);
/*!
* \brief Captures a frame to a CUDA device in video memory.
@ -1838,7 +1849,8 @@ NVFBCSTATUS NVFBCAPI NvFBCToCudaSetUp(const NVFBC_SESSION_HANDLE sessionHandle,
* \see NvFBCCreateCaptureSession \n
* \see NvFBCToCudaSetUp
*/
NVFBCSTATUS NVFBCAPI NvFBCToCudaGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_GRAB_FRAME_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToCudaGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_GRAB_FRAME_PARAMS *pParams);
/*!
* \brief Sets up a capture to OpenGL buffer in video memory session.
@ -1865,7 +1877,8 @@ NVFBCSTATUS NVFBCAPI NvFBCToCudaGrabFrame(const NVFBC_SESSION_HANDLE sessionHand
* ::NVFBC_ERR_GL \n
* ::NVFBC_ERR_X
*/
NVFBCSTATUS NVFBCAPI NvFBCToGLSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_SETUP_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToGLSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_SETUP_PARAMS *pParams);
/*!
* \brief Captures a frame to an OpenGL buffer in video memory.
@ -1893,7 +1906,8 @@ NVFBCSTATUS NVFBCAPI NvFBCToGLSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NV
* \see NvFBCCreateCaptureSession \n
* \see NvFBCToCudaSetUp
*/
NVFBCSTATUS NVFBCAPI NvFBCToGLGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_GRAB_FRAME_PARAMS *pParams);
NVFBCSTATUS NVFBCAPI
NvFBCToGLGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_GRAB_FRAME_PARAMS *pParams);
/*!
* \cond FBC_PFN
@ -1966,7 +1980,8 @@ typedef struct
* ::NVFBC_ERR_INVALID_PTR \n
* ::NVFBC_ERR_API_VERSION
*/
NVFBCSTATUS NVFBCAPI NvFBCCreateInstance(NVFBC_API_FUNCTION_LIST *pFunctionList);
NVFBCSTATUS NVFBCAPI
NvFBCCreateInstance(NVFBC_API_FUNCTION_LIST *pFunctionList);
/*!
* \ingroup FBC_FUNC
*

File diff suppressed because it is too large Load diff

View file

@ -31,12 +31,14 @@ int device_state_filter = DEVICE_STATE_ACTIVE;
namespace audio {
template <class T>
void Release(T *p) {
void
Release(T *p) {
p->Release();
}
template <class T>
void co_task_free(T *p) {
void
co_task_free(T *p) {
CoTaskMemFree((LPVOID) p);
}
@ -65,7 +67,8 @@ public:
PROPVARIANT prop;
};
const wchar_t *no_null(const wchar_t *str) {
const wchar_t *
no_null(const wchar_t *str) {
return str ? str : L"Unknown";
}
@ -100,7 +103,8 @@ struct format_t {
SPEAKER_SIDE_RIGHT }
};
void set_wave_format(audio::wave_format_t &wave_format, const format_t &format) {
void
set_wave_format(audio::wave_format_t &wave_format, const format_t &format) {
wave_format->nChannels = format.channels;
wave_format->nBlockAlign = wave_format->nChannels * wave_format->wBitsPerSample / 8;
wave_format->nAvgBytesPerSec = wave_format->nSamplesPerSec * wave_format->nBlockAlign;
@ -110,7 +114,8 @@ void set_wave_format(audio::wave_format_t &wave_format, const format_t &format)
}
}
audio_client_t make_audio_client(device_t &device, const format_t &format) {
audio_client_t
make_audio_client(device_t &device, const format_t &format) {
audio_client_t audio_client;
auto status = device->Activate(
IID_IAudioClient,
@ -171,7 +176,8 @@ audio_client_t make_audio_client(device_t &device, const format_t &format) {
return audio_client;
}
void print_device(device_t &device) {
void
print_device(device_t &device) {
audio::wstring_t wstring;
DWORD device_state;
@ -231,14 +237,16 @@ void print_device(device_t &device) {
}
} // namespace audio
void print_help() {
void
print_help() {
std::cout
<< "==== Help ===="sv << std::endl
<< "Usage:"sv << std::endl
<< " audio-info [Active|Disabled|Unplugged|Not-Present]" << std::endl;
}
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_SPEED_OVER_MEMORY);
auto fg = util::fail_guard([]() {

View file

@ -11,7 +11,8 @@
using namespace std::literals;
namespace dxgi {
template <class T>
void Release(T *dxgi) {
void
Release(T *dxgi) {
dxgi->Release();
}
@ -24,7 +25,8 @@ using dup_t = util::safe_ptr<IDXGIOutputDuplication, Release<IDXGIOutputDup
} // namespace dxgi
LSTATUS set_gpu_preference(int preference) {
LSTATUS
set_gpu_preference(int preference) {
// The GPU preferences key uses app path as the value name.
WCHAR executable_path[MAX_PATH];
GetModuleFileNameW(NULL, executable_path, ARRAYSIZE(executable_path));
@ -46,7 +48,8 @@ LSTATUS set_gpu_preference(int preference) {
return ERROR_SUCCESS;
}
HRESULT test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output) {
HRESULT
test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output) {
D3D_FEATURE_LEVEL featureLevels[] {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
@ -85,7 +88,8 @@ HRESULT test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output)
return output1->DuplicateOutput((IUnknown *) device.get(), &dup);
}
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
HRESULT status;
// Display name may be omitted

View file

@ -12,7 +12,8 @@
using namespace std::literals;
namespace dxgi {
template <class T>
void Release(T *dxgi) {
void
Release(T *dxgi) {
dxgi->Release();
}
@ -22,7 +23,8 @@ using output_t = util::safe_ptr<IDXGIOutput, Release<IDXGIOutput>>;
} // namespace dxgi
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
HRESULT status;
dxgi::factory1_t::pointer factory_p {};

View file

@ -19,7 +19,8 @@
* To run a command, such as 'ipconfig /flushdns', with administrative privileges, execute:
* elevator.exe cmd /C "ipconfig /flushdns"
*/
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
// Check if the user provided at least one argument (the command to run)
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " <command> [arguments]" << std::endl;

Some files were not shown because too many files have changed in this diff Show more