mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-18 01:46:47 +08:00
[refactor] reorganize platform and wire sources
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-05-15
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DISPLAY_INFO_H_
|
||||
#define _DISPLAY_INFO_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
class DisplayInfo {
|
||||
public:
|
||||
DisplayInfo(std::string name, int left, int top, int right, int bottom)
|
||||
: name(name), left(left), top(top), right(right), bottom(bottom) {
|
||||
width = right - left;
|
||||
height = bottom - top;
|
||||
}
|
||||
DisplayInfo(void* handle, std::string name, bool is_primary, int left,
|
||||
int top, int right, int bottom)
|
||||
: handle(handle),
|
||||
name(name),
|
||||
is_primary(is_primary),
|
||||
left(left),
|
||||
top(top),
|
||||
right(right),
|
||||
bottom(bottom) {
|
||||
width = right - left;
|
||||
height = bottom - top;
|
||||
}
|
||||
~DisplayInfo() {}
|
||||
|
||||
void* handle = nullptr;
|
||||
std::string name = "";
|
||||
bool is_primary = false;
|
||||
int left = 0;
|
||||
int top = 0;
|
||||
int right = 0;
|
||||
int bottom = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef CROSSDESK_COMMON_FILESYSTEM_UTF8_H_
|
||||
#define CROSSDESK_COMMON_FILESYSTEM_UTF8_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
inline std::filesystem::path PathFromUtf8(std::string_view value) {
|
||||
#if defined(__cpp_char8_t)
|
||||
const auto *begin = reinterpret_cast<const char8_t *>(value.data());
|
||||
return std::filesystem::path(std::u8string(begin, begin + value.size()));
|
||||
#else
|
||||
return std::filesystem::u8path(value.begin(), value.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
#endif // CROSSDESK_COMMON_FILESYSTEM_UTF8_H_
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "nv12_scaler.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
#include "libyuv/planar_functions.h"
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
int ScaleNv12ViaI420(const uint8_t* src_y, int src_stride_y,
|
||||
const uint8_t* src_uv, int src_stride_uv, int src_width,
|
||||
int src_height, uint8_t* dst_y, int dst_stride_y,
|
||||
uint8_t* dst_uv, int dst_stride_uv, int dst_width,
|
||||
int dst_height, libyuv::FilterMode filtering,
|
||||
std::vector<uint8_t>* scratch_buffer) {
|
||||
if (!src_y || !src_uv || !dst_y || !dst_uv || !scratch_buffer ||
|
||||
src_width <= 0 || src_height <= 0 || dst_width <= 0 || dst_height <= 0 ||
|
||||
(src_width & 1) != 0 || (src_height & 1) != 0 || (dst_width & 1) != 0 ||
|
||||
(dst_height & 1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int src_chroma_width = src_width / 2;
|
||||
const int src_chroma_height = src_height / 2;
|
||||
const int dst_chroma_width = dst_width / 2;
|
||||
const int dst_chroma_height = dst_height / 2;
|
||||
const size_t src_chroma_size =
|
||||
static_cast<size_t>(src_chroma_width) * src_chroma_height;
|
||||
const size_t dst_chroma_size =
|
||||
static_cast<size_t>(dst_chroma_width) * dst_chroma_height;
|
||||
const size_t max_size = std::numeric_limits<size_t>::max();
|
||||
if (src_chroma_size > max_size / 2 || dst_chroma_size > max_size / 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const size_t src_planes_size = 2 * src_chroma_size;
|
||||
const size_t dst_planes_size = 2 * dst_chroma_size;
|
||||
if (src_planes_size > max_size - dst_planes_size) {
|
||||
return -1;
|
||||
}
|
||||
scratch_buffer->resize(src_planes_size + dst_planes_size);
|
||||
uint8_t* src_u = scratch_buffer->data();
|
||||
uint8_t* src_v = src_u + src_chroma_size;
|
||||
uint8_t* dst_u = src_v + src_chroma_size;
|
||||
uint8_t* dst_v = dst_u + dst_chroma_size;
|
||||
|
||||
libyuv::SplitUVPlane(src_uv, src_stride_uv, src_u, src_chroma_width, src_v,
|
||||
src_chroma_width, src_chroma_width, src_chroma_height);
|
||||
const int result = libyuv::I420Scale(
|
||||
src_y, src_stride_y, src_u, src_chroma_width, src_v, src_chroma_width,
|
||||
src_width, src_height, dst_y, dst_stride_y, dst_u, dst_chroma_width,
|
||||
dst_v, dst_chroma_width, dst_width, dst_height, filtering);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
libyuv::MergeUVPlane(dst_u, dst_chroma_width, dst_v, dst_chroma_width, dst_uv,
|
||||
dst_stride_uv, dst_chroma_width, dst_chroma_height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace crossdesk
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef CROSSDESK_COMMON_NV12_SCALER_H_
|
||||
#define CROSSDESK_COMMON_NV12_SCALER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "libyuv/scale.h"
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
// Scales NV12 by separating the interleaved chroma plane before filtering.
|
||||
// This avoids the downward chroma rounding bias in libyuv::NV12Scale while
|
||||
// preserving the requested filtering quality.
|
||||
int ScaleNv12ViaI420(const uint8_t* src_y, int src_stride_y,
|
||||
const uint8_t* src_uv, int src_stride_uv, int src_width,
|
||||
int src_height, uint8_t* dst_y, int dst_stride_y,
|
||||
uint8_t* dst_uv, int dst_stride_uv, int dst_width,
|
||||
int dst_height, libyuv::FilterMode filtering,
|
||||
std::vector<uint8_t>* scratch_buffer);
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
#endif // CROSSDESK_COMMON_NV12_SCALER_H_
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2023-12-18
|
||||
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
std::string GetMac();
|
||||
std::string GetHostName();
|
||||
bool IsWaylandSession();
|
||||
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "rounded_corner_button.h"
|
||||
|
||||
namespace crossdesk {
|
||||
bool RoundedCornerButton(const char* label, const ImVec2& size, float rounding,
|
||||
ImDrawFlags round_flags, bool enabled,
|
||||
ImU32 normal_col, ImU32 hover_col, ImU32 active_col,
|
||||
ImU32 border_col) {
|
||||
ImGuiWindow* current_window = ImGui::GetCurrentWindow();
|
||||
if (current_window->SkipItems) return false;
|
||||
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
|
||||
ImGuiID button_id = current_window->GetID(label);
|
||||
ImVec2 cursor_pos = current_window->DC.CursorPos;
|
||||
ImVec2 button_size = ImGui::CalcItemSize(size, 0.0f, 0.0f);
|
||||
ImRect button_rect(cursor_pos, ImVec2(cursor_pos.x + button_size.x,
|
||||
cursor_pos.y + button_size.y));
|
||||
ImGui::ItemSize(button_rect);
|
||||
if (!ImGui::ItemAdd(button_rect, button_id)) return false;
|
||||
|
||||
bool is_hovered = false, is_held = false;
|
||||
bool is_pressed = false;
|
||||
if (enabled) {
|
||||
is_pressed =
|
||||
ImGui::ButtonBehavior(button_rect, button_id, &is_hovered, &is_held);
|
||||
}
|
||||
|
||||
if (normal_col == 0) normal_col = ImGui::GetColorU32(ImGuiCol_Button);
|
||||
if (hover_col == 0) hover_col = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
|
||||
if (active_col == 0) active_col = ImGui::GetColorU32(ImGuiCol_ButtonActive);
|
||||
if (border_col == 0) border_col = ImGui::GetColorU32(ImGuiCol_Border);
|
||||
|
||||
ImU32 fill_color = normal_col;
|
||||
if (is_held && is_hovered)
|
||||
fill_color = active_col;
|
||||
else if (is_hovered)
|
||||
fill_color = hover_col;
|
||||
|
||||
if (!enabled) fill_color = IM_COL32(120, 120, 120, 180);
|
||||
|
||||
ImDrawList* window_draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
window_draw_list->AddRectFilled(button_rect.Min, button_rect.Max, fill_color,
|
||||
rounding, round_flags);
|
||||
|
||||
if (style.FrameBorderSize > 0.0f) {
|
||||
window_draw_list->AddRect(button_rect.Min, button_rect.Max, border_col,
|
||||
rounding, round_flags, style.FrameBorderSize);
|
||||
}
|
||||
|
||||
ImU32 text_color =
|
||||
ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled);
|
||||
|
||||
const char* label_end = ImGui::FindRenderedTextEnd(label);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImGui::ColorConvertU32ToFloat4(text_color));
|
||||
ImGui::RenderTextClipped(button_rect.Min, button_rect.Max, label, label_end,
|
||||
nullptr, ImVec2(0.5f, 0.5f), &button_rect);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
return is_pressed;
|
||||
}
|
||||
} // namespace crossdesk
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2026-02-26
|
||||
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ROUNDED_CORNER_BUTTON_H_
|
||||
#define _ROUNDED_CORNER_BUTTON_H_
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
namespace crossdesk {
|
||||
bool RoundedCornerButton(const char* label, const ImVec2& size, float rounding,
|
||||
ImDrawFlags round_flags, bool enabled = true,
|
||||
ImU32 normal_col = 0, ImU32 hover_col = 0,
|
||||
ImU32 active_col = 0, ImU32 border_col = 0);
|
||||
} // namespace crossdesk
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "shared_cursor_state.h"
|
||||
|
||||
#include <remote_action.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace crossdesk {
|
||||
namespace {
|
||||
|
||||
std::mutex g_cursor_state_mutex;
|
||||
SharedCursorState g_cursor_state;
|
||||
bool g_cursor_state_available = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
void PublishSharedCursorState(bool visible, RemoteCursorShape shape) {
|
||||
std::lock_guard<std::mutex> lock(g_cursor_state_mutex);
|
||||
++g_cursor_state.generation;
|
||||
g_cursor_state.visible = visible;
|
||||
g_cursor_state.shape = visible ? shape : RemoteCursorShape::none;
|
||||
g_cursor_state_available = true;
|
||||
}
|
||||
|
||||
bool GetSharedCursorState(SharedCursorState* state) {
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(g_cursor_state_mutex);
|
||||
if (!g_cursor_state_available) {
|
||||
return false;
|
||||
}
|
||||
*state = g_cursor_state;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearSharedCursorState() {
|
||||
std::lock_guard<std::mutex> lock(g_cursor_state_mutex);
|
||||
++g_cursor_state.generation;
|
||||
g_cursor_state.visible = false;
|
||||
g_cursor_state.shape = RemoteCursorShape::none;
|
||||
g_cursor_state_available = false;
|
||||
}
|
||||
|
||||
} // namespace crossdesk
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CROSSDESK_COMMON_SHARED_CURSOR_STATE_H_
|
||||
#define CROSSDESK_COMMON_SHARED_CURSOR_STATE_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <remote_cursor_shape.h>
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
struct SharedCursorState {
|
||||
uint64_t generation = 0;
|
||||
bool visible = false;
|
||||
RemoteCursorShape shape = RemoteCursorShape::default_cursor;
|
||||
};
|
||||
|
||||
void PublishSharedCursorState(bool visible, RemoteCursorShape shape);
|
||||
bool GetSharedCursorState(SharedCursorState* state);
|
||||
void ClearSharedCursorState();
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
#endif // CROSSDESK_COMMON_SHARED_CURSOR_STATE_H_
|
||||
Reference in New Issue
Block a user