mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-27 05:34:00 +00:00
文件浏览器
This commit is contained in:
@@ -117,6 +117,7 @@ list(REMOVE_DUPLICATES USER_KELF_APP_NAMES)
|
|||||||
set(USER_APP_OUTPUTS)
|
set(USER_APP_OUTPUTS)
|
||||||
set(USER_APP_NAMES)
|
set(USER_APP_NAMES)
|
||||||
set(RAMDISK_SHELL_APPS)
|
set(RAMDISK_SHELL_APPS)
|
||||||
|
set(RAMDISK_UWM_APPS)
|
||||||
set(RAMDISK_DRIVER_APPS)
|
set(RAMDISK_DRIVER_APPS)
|
||||||
set(RAMDISK_SYSTEM_APPS)
|
set(RAMDISK_SYSTEM_APPS)
|
||||||
set(RAMDISK_ROOT_APPS)
|
set(RAMDISK_ROOT_APPS)
|
||||||
@@ -279,7 +280,9 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
|||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND USER_APP_OUTPUTS "${_app_out}")
|
list(APPEND USER_APP_OUTPUTS "${_app_out}")
|
||||||
if(_app_name MATCHES ".*drv$")
|
if(_app_name STREQUAL "file_explorer")
|
||||||
|
list(APPEND RAMDISK_UWM_APPS "${_app_out}")
|
||||||
|
elseif(_app_name MATCHES ".*drv$")
|
||||||
list(APPEND RAMDISK_DRIVER_APPS "${_app_out}")
|
list(APPEND RAMDISK_DRIVER_APPS "${_app_out}")
|
||||||
elseif(_app_name STREQUAL "hello")
|
elseif(_app_name STREQUAL "hello")
|
||||||
list(APPEND RAMDISK_ROOT_APPS "${_app_out}")
|
list(APPEND RAMDISK_ROOT_APPS "${_app_out}")
|
||||||
@@ -349,6 +352,10 @@ foreach(_app IN LISTS RAMDISK_SHELL_APPS)
|
|||||||
get_filename_component(_app_file "${_app}" NAME)
|
get_filename_component(_app_file "${_app}" NAME)
|
||||||
list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/shell/${_app_file}")
|
list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/shell/${_app_file}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
foreach(_app IN LISTS RAMDISK_UWM_APPS)
|
||||||
|
get_filename_component(_app_file "${_app}" NAME)
|
||||||
|
list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/shell/uwm/${_app_file}")
|
||||||
|
endforeach()
|
||||||
foreach(_app IN LISTS RAMDISK_ROOT_APPS)
|
foreach(_app IN LISTS RAMDISK_ROOT_APPS)
|
||||||
get_filename_component(_app_file "${_app}" NAME)
|
get_filename_component(_app_file "${_app}" NAME)
|
||||||
list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/${_app_file}")
|
list(APPEND RAMDISK_COPY_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${_app}" "${RAMDISK_ROOT}/${_app_file}")
|
||||||
@@ -367,7 +374,7 @@ add_custom_command(
|
|||||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${RAMDISK_ROOT}"
|
COMMAND ${CMAKE_COMMAND} -E rm -rf "${RAMDISK_ROOT}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}"
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/ramdisk" "${RAMDISK_ROOT}"
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/ramdisk" "${RAMDISK_ROOT}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}/system" "${RAMDISK_ROOT}/shell" "${RAMDISK_ROOT}/driver" "${RAMDISK_ROOT}/dev"
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}/system" "${RAMDISK_ROOT}/shell" "${RAMDISK_ROOT}/shell/uwm" "${RAMDISK_ROOT}/driver" "${RAMDISK_ROOT}/dev"
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${KERNEL_SYMBOLS_FILE}" "${RAMDISK_ROOT}/system/kernel.sym"
|
COMMAND ${CMAKE_COMMAND} -E copy "${KERNEL_SYMBOLS_FILE}" "${RAMDISK_ROOT}/system/kernel.sym"
|
||||||
${RAMDISK_COPY_COMMANDS}
|
${RAMDISK_COPY_COMMANDS}
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch "${RAMDISK_ROOT_STAMP}"
|
COMMAND ${CMAKE_COMMAND} -E touch "${RAMDISK_ROOT_STAMP}"
|
||||||
|
|||||||
1116
cleonos/c/apps/file_explorer_main.c
Normal file
1116
cleonos/c/apps/file_explorer_main.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,13 +5,155 @@
|
|||||||
#define USH_QRCODE_MAX_VERSION 15
|
#define USH_QRCODE_MAX_VERSION 15
|
||||||
#define USH_QRCODE_BORDER 4U
|
#define USH_QRCODE_BORDER 4U
|
||||||
#define USH_QRCODE_MAX_MODULES ((USH_QRCODE_MAX_VERSION * 4U) + 17U + (USH_QRCODE_BORDER * 2U))
|
#define USH_QRCODE_MAX_MODULES ((USH_QRCODE_MAX_VERSION * 4U) + 17U + (USH_QRCODE_BORDER * 2U))
|
||||||
#define USH_QRCODE_CANVAS_MAX 1024U
|
#define USH_QRCODE_CANVAS_MAX 640U
|
||||||
|
#define USH_QRCODE_TTY_DISPLAY 1ULL
|
||||||
|
#define USH_QRCODE_TITLE_H 34
|
||||||
|
#define USH_QRCODE_FOOTER_H 34
|
||||||
|
#define USH_QRCODE_PAD 24
|
||||||
|
#define USH_QRCODE_CLOSE_W 44
|
||||||
|
#define USH_QRCODE_WINDOW_DEFAULT_W 520
|
||||||
|
#define USH_QRCODE_WINDOW_DEFAULT_H 600
|
||||||
|
#define USH_QRCODE_WINDOW_MIN_W 320
|
||||||
|
#define USH_QRCODE_WINDOW_MIN_H 380
|
||||||
|
|
||||||
#define USH_QRCODE_COLOR_DARK 0x00000000ULL
|
#define USH_QRCODE_COLOR_DARK 0x00000000U
|
||||||
#define USH_QRCODE_COLOR_LIGHT 0x00FFFFFFULL
|
#define USH_QRCODE_COLOR_LIGHT 0x00FFFFFFU
|
||||||
|
#define USH_QRCODE_COLOR_DESKTOP 0x00F3F3F3U
|
||||||
|
#define USH_QRCODE_COLOR_TITLE 0x000078D7U
|
||||||
|
#define USH_QRCODE_COLOR_CLOSE 0x00E81123U
|
||||||
|
#define USH_QRCODE_COLOR_TEXT 0x00232323U
|
||||||
|
#define USH_QRCODE_COLOR_MUTED 0x00666666U
|
||||||
|
#define USH_QRCODE_COLOR_BORDER 0x00D0D0D0U
|
||||||
|
#define USH_QRCODE_COLOR_PANEL 0x00FFFFFFU
|
||||||
|
|
||||||
|
#define USH_QRCODE_GLYPH7(r0, r1, r2, r3, r4, r5, r6) \
|
||||||
|
(((u64)(r0) << 30U) | ((u64)(r1) << 25U) | ((u64)(r2) << 20U) | ((u64)(r3) << 15U) | \
|
||||||
|
((u64)(r4) << 10U) | ((u64)(r5) << 5U) | (u64)(r6))
|
||||||
|
|
||||||
static unsigned int ush_qrcode_canvas[USH_QRCODE_CANVAS_MAX][USH_QRCODE_CANVAS_MAX];
|
static unsigned int ush_qrcode_canvas[USH_QRCODE_CANVAS_MAX][USH_QRCODE_CANVAS_MAX];
|
||||||
|
|
||||||
|
static int ush_qrcode_clampi(int value, int min_value, int max_value) {
|
||||||
|
if (value < min_value) {
|
||||||
|
return min_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > max_value) {
|
||||||
|
return max_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_qrcode_u64_as_i32(u64 raw) {
|
||||||
|
return (int)(i64)raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char ush_qrcode_upper_char(char ch) {
|
||||||
|
if (ch >= 'a' && ch <= 'z') {
|
||||||
|
return (char)(ch - ('a' - 'A'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 ush_qrcode_glyph_mask(char ch) {
|
||||||
|
switch (ush_qrcode_upper_char(ch)) {
|
||||||
|
case 'C':
|
||||||
|
return USH_QRCODE_GLYPH7(14U, 17U, 16U, 16U, 16U, 17U, 14U);
|
||||||
|
case 'D':
|
||||||
|
return USH_QRCODE_GLYPH7(30U, 17U, 17U, 17U, 17U, 17U, 30U);
|
||||||
|
case 'E':
|
||||||
|
return USH_QRCODE_GLYPH7(31U, 16U, 16U, 30U, 16U, 16U, 31U);
|
||||||
|
case 'L':
|
||||||
|
return USH_QRCODE_GLYPH7(16U, 16U, 16U, 16U, 16U, 16U, 31U);
|
||||||
|
case 'O':
|
||||||
|
return USH_QRCODE_GLYPH7(14U, 17U, 17U, 17U, 17U, 17U, 14U);
|
||||||
|
case 'P':
|
||||||
|
return USH_QRCODE_GLYPH7(30U, 17U, 17U, 30U, 16U, 16U, 16U);
|
||||||
|
case 'Q':
|
||||||
|
return USH_QRCODE_GLYPH7(14U, 17U, 17U, 17U, 21U, 18U, 13U);
|
||||||
|
case 'R':
|
||||||
|
return USH_QRCODE_GLYPH7(30U, 17U, 17U, 30U, 20U, 18U, 17U);
|
||||||
|
case 'S':
|
||||||
|
return USH_QRCODE_GLYPH7(15U, 16U, 16U, 14U, 1U, 1U, 30U);
|
||||||
|
case 'T':
|
||||||
|
return USH_QRCODE_GLYPH7(31U, 4U, 4U, 4U, 4U, 4U, 4U);
|
||||||
|
default:
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_qrcode_fill_rect(int canvas_w, int canvas_h, int x, int y, int w, int h, unsigned int color) {
|
||||||
|
int left;
|
||||||
|
int top;
|
||||||
|
int right;
|
||||||
|
int bottom;
|
||||||
|
int row;
|
||||||
|
|
||||||
|
if (canvas_w <= 0 || canvas_h <= 0 || canvas_w > (int)USH_QRCODE_CANVAS_MAX ||
|
||||||
|
canvas_h > (int)USH_QRCODE_CANVAS_MAX || w <= 0 || h <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
left = ush_qrcode_clampi(x, 0, canvas_w);
|
||||||
|
top = ush_qrcode_clampi(y, 0, canvas_h);
|
||||||
|
right = ush_qrcode_clampi(x + w, 0, canvas_w);
|
||||||
|
bottom = ush_qrcode_clampi(y + h, 0, canvas_h);
|
||||||
|
if (left >= right || top >= bottom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (row = top; row < bottom; row++) {
|
||||||
|
int col;
|
||||||
|
for (col = left; col < right; col++) {
|
||||||
|
ush_qrcode_canvas[row][col] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_qrcode_stroke_rect(int canvas_w, int canvas_h, int x, int y, int w, int h, unsigned int color) {
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, x, y, w, 1, color);
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, x, y + h - 1, w, 1, color);
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, x, y, 1, h, color);
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, x + w - 1, y, 1, h, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_qrcode_draw_char(int canvas_w, int canvas_h, int x, int y, char ch, int scale, unsigned int color) {
|
||||||
|
u64 mask = ush_qrcode_glyph_mask(ch);
|
||||||
|
int row;
|
||||||
|
|
||||||
|
if (mask == 0ULL || scale <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (row = 0; row < 7; row++) {
|
||||||
|
int col;
|
||||||
|
for (col = 0; col < 5; col++) {
|
||||||
|
unsigned int bit_index = (unsigned int)((6 - row) * 5 + (4 - col));
|
||||||
|
if ((mask & (1ULL << bit_index)) != 0ULL) {
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, x + (col * scale), y + (row * scale), scale, scale, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_qrcode_draw_text(int canvas_w, int canvas_h, int x, int y, const char *text, int scale,
|
||||||
|
unsigned int color) {
|
||||||
|
int cursor_x = x;
|
||||||
|
|
||||||
|
if (text == (const char *)0 || scale <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*text != '\0' && cursor_x + (5 * scale) < canvas_w) {
|
||||||
|
if (*text != ' ') {
|
||||||
|
ush_qrcode_draw_char(canvas_w, canvas_h, cursor_x, y, *text, scale, color);
|
||||||
|
}
|
||||||
|
cursor_x += 6 * scale;
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ush_qrcode_streq_ignore_case(const char *left, const char *right) {
|
static int ush_qrcode_streq_ignore_case(const char *left, const char *right) {
|
||||||
u64 i = 0ULL;
|
u64 i = 0ULL;
|
||||||
|
|
||||||
@@ -200,109 +342,268 @@ static void ush_qrcode_emit_ascii(const uint8_t qrcode[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ush_qrcode_build_canvas(const uint8_t qrcode[], u64 module_pixels, u64 *out_side_pixels) {
|
static void ush_qrcode_choose_window_geometry(const cleonos_fb_info *fb_info, int *out_x, int *out_y, int *out_w,
|
||||||
int qr_size = qrcodegen_getSize(qrcode);
|
int *out_h) {
|
||||||
u64 side_modules;
|
int screen_w = 800;
|
||||||
u64 side_pixels;
|
int screen_h = 600;
|
||||||
u64 y;
|
int max_w;
|
||||||
u64 x;
|
int max_h;
|
||||||
|
int win_w;
|
||||||
|
int win_h;
|
||||||
|
|
||||||
if (out_side_pixels == (u64 *)0 || module_pixels == 0ULL || qr_size <= 0) {
|
if (fb_info != (const cleonos_fb_info *)0 && fb_info->width > 0ULL && fb_info->height > 0ULL &&
|
||||||
|
fb_info->width <= 4096ULL && fb_info->height <= 4096ULL) {
|
||||||
|
screen_w = (int)fb_info->width;
|
||||||
|
screen_h = (int)fb_info->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_w = screen_w - 80;
|
||||||
|
max_h = screen_h - 96;
|
||||||
|
if (max_w < USH_QRCODE_WINDOW_MIN_W) {
|
||||||
|
max_w = screen_w;
|
||||||
|
}
|
||||||
|
if (max_h < USH_QRCODE_WINDOW_MIN_H) {
|
||||||
|
max_h = screen_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
win_w = ush_qrcode_clampi(USH_QRCODE_WINDOW_DEFAULT_W, USH_QRCODE_WINDOW_MIN_W, max_w);
|
||||||
|
win_h = ush_qrcode_clampi(USH_QRCODE_WINDOW_DEFAULT_H, USH_QRCODE_WINDOW_MIN_H, max_h);
|
||||||
|
if (win_w > (int)USH_QRCODE_CANVAS_MAX) {
|
||||||
|
win_w = (int)USH_QRCODE_CANVAS_MAX;
|
||||||
|
}
|
||||||
|
if (win_h > (int)USH_QRCODE_CANVAS_MAX) {
|
||||||
|
win_h = (int)USH_QRCODE_CANVAS_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_w = win_w;
|
||||||
|
*out_h = win_h;
|
||||||
|
*out_x = (screen_w > win_w) ? ((screen_w - win_w) / 2) : 0;
|
||||||
|
*out_y = (screen_h > win_h) ? ((screen_h - win_h) / 2) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_qrcode_draw_window_canvas(const uint8_t qrcode[], int canvas_w, int canvas_h) {
|
||||||
|
int qr_size = qrcodegen_getSize(qrcode);
|
||||||
|
int border = (int)USH_QRCODE_BORDER;
|
||||||
|
int side_modules;
|
||||||
|
int content_w;
|
||||||
|
int content_h;
|
||||||
|
int qr_area;
|
||||||
|
int module_pixels;
|
||||||
|
int side_pixels;
|
||||||
|
int qr_x;
|
||||||
|
int qr_y;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
if (qrcode == (const uint8_t *)0 || qr_size <= 0 || canvas_w <= 0 || canvas_h <= 0 ||
|
||||||
|
canvas_w > (int)USH_QRCODE_CANVAS_MAX || canvas_h > (int)USH_QRCODE_CANVAS_MAX) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
side_modules = (u64)qr_size + (u64)(USH_QRCODE_BORDER * 2U);
|
side_modules = qr_size + (border * 2);
|
||||||
if (side_modules == 0ULL || side_modules > (u64)USH_QRCODE_MAX_MODULES) {
|
if (side_modules <= 0 || side_modules > (int)USH_QRCODE_MAX_MODULES) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
content_w = canvas_w - (USH_QRCODE_PAD * 2);
|
||||||
|
content_h = canvas_h - USH_QRCODE_TITLE_H - USH_QRCODE_FOOTER_H - (USH_QRCODE_PAD * 2);
|
||||||
|
qr_area = (content_w < content_h) ? content_w : content_h;
|
||||||
|
module_pixels = qr_area / side_modules;
|
||||||
|
if (module_pixels <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
side_pixels = side_modules * module_pixels;
|
side_pixels = side_modules * module_pixels;
|
||||||
if (side_pixels == 0ULL || side_pixels > (u64)USH_QRCODE_CANVAS_MAX) {
|
qr_x = (canvas_w - side_pixels) / 2;
|
||||||
return 0;
|
qr_y = USH_QRCODE_TITLE_H + USH_QRCODE_PAD + ((content_h - side_pixels) / 2);
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0ULL; y < side_pixels; y++) {
|
ush_qrcode_fill_rect(canvas_w, canvas_h, 0, 0, canvas_w, canvas_h, USH_QRCODE_COLOR_DESKTOP);
|
||||||
for (x = 0ULL; x < side_pixels; x++) {
|
ush_qrcode_fill_rect(canvas_w, canvas_h, 0, 0, canvas_w, USH_QRCODE_TITLE_H, USH_QRCODE_COLOR_TITLE);
|
||||||
int qx = (int)(x / module_pixels) - (int)USH_QRCODE_BORDER;
|
ush_qrcode_fill_rect(canvas_w, canvas_h, canvas_w - USH_QRCODE_CLOSE_W, 0, USH_QRCODE_CLOSE_W,
|
||||||
int qy = (int)(y / module_pixels) - (int)USH_QRCODE_BORDER;
|
USH_QRCODE_TITLE_H, USH_QRCODE_COLOR_CLOSE);
|
||||||
int dark =
|
ush_qrcode_draw_text(canvas_w, canvas_h, 14, 10, "QRCODE", 1, USH_QRCODE_COLOR_LIGHT);
|
||||||
(qx >= 0 && qy >= 0 && qx < qr_size && qy < qr_size && qrcodegen_getModule(qrcode, qx, qy)) ? 1 : 0;
|
ush_qrcode_fill_rect(canvas_w, canvas_h, canvas_w - 28, 11, 14, 2, USH_QRCODE_COLOR_LIGHT);
|
||||||
ush_qrcode_canvas[y][x] =
|
ush_qrcode_fill_rect(canvas_w, canvas_h, canvas_w - 28, 22, 14, 2, USH_QRCODE_COLOR_LIGHT);
|
||||||
(dark != 0) ? (unsigned int)USH_QRCODE_COLOR_DARK : (unsigned int)USH_QRCODE_COLOR_LIGHT;
|
ush_qrcode_fill_rect(canvas_w, canvas_h, canvas_w - 22, 15, 2, 6, USH_QRCODE_COLOR_LIGHT);
|
||||||
|
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, qr_x - 10, qr_y - 10, side_pixels + 20, side_pixels + 20,
|
||||||
|
USH_QRCODE_COLOR_PANEL);
|
||||||
|
ush_qrcode_stroke_rect(canvas_w, canvas_h, qr_x - 10, qr_y - 10, side_pixels + 20, side_pixels + 20,
|
||||||
|
USH_QRCODE_COLOR_BORDER);
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, qr_x, qr_y, side_pixels, side_pixels, USH_QRCODE_COLOR_LIGHT);
|
||||||
|
|
||||||
|
for (y = -border; y < qr_size + border; y++) {
|
||||||
|
int x;
|
||||||
|
for (x = -border; x < qr_size + border; x++) {
|
||||||
|
int dark = (x >= 0 && y >= 0 && x < qr_size && y < qr_size && qrcodegen_getModule(qrcode, x, y)) ? 1 : 0;
|
||||||
|
if (dark != 0) {
|
||||||
|
int px = qr_x + ((x + border) * module_pixels);
|
||||||
|
int py = qr_y + ((y + border) * module_pixels);
|
||||||
|
ush_qrcode_fill_rect(canvas_w, canvas_h, px, py, module_pixels, module_pixels,
|
||||||
|
USH_QRCODE_COLOR_DARK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_side_pixels = side_pixels;
|
ush_qrcode_draw_text(canvas_w, canvas_h, 22, canvas_h - 24, "PRESS Q TO CLOSE", 1, USH_QRCODE_COLOR_MUTED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ush_qrcode_emit_pixels(const uint8_t qrcode[]) {
|
static int ush_qrcode_present_window(u64 window_id, int width, int height) {
|
||||||
int qr_size = qrcodegen_getSize(qrcode);
|
cleonos_wm_present_req req;
|
||||||
u64 side_modules;
|
|
||||||
cleonos_fb_info fb_info;
|
|
||||||
cleonos_fb_blit_req req;
|
|
||||||
u64 module_pixels_x;
|
|
||||||
u64 module_pixels_y;
|
|
||||||
u64 module_pixels;
|
|
||||||
u64 module_pixels_canvas_cap;
|
|
||||||
u64 side_pixels = 0ULL;
|
|
||||||
u64 draw_w;
|
|
||||||
u64 draw_h;
|
|
||||||
|
|
||||||
if (qr_size <= 0) {
|
if (window_id == 0ULL || width <= 0 || height <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
side_modules = (u64)qr_size + (u64)(USH_QRCODE_BORDER * 2U);
|
req.window_id = window_id;
|
||||||
if (side_modules == 0ULL || side_modules > (u64)USH_QRCODE_MAX_MODULES) {
|
req.pixels_ptr = (u64)(usize)&ush_qrcode_canvas[0][0];
|
||||||
|
req.src_width = (u64)(unsigned int)width;
|
||||||
|
req.src_height = (u64)(unsigned int)height;
|
||||||
|
req.src_pitch_bytes = (u64)USH_QRCODE_CANVAS_MAX * 4ULL;
|
||||||
|
return (cleonos_sys_wm_present(&req) != 0ULL) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_qrcode_close_hit(int width, int local_x, int local_y) {
|
||||||
|
return (local_x >= width - USH_QRCODE_CLOSE_W && local_x < width && local_y >= 0 &&
|
||||||
|
local_y < USH_QRCODE_TITLE_H)
|
||||||
|
? 1
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_qrcode_window_loop(u64 window_id, int width, int height, int x, int y) {
|
||||||
|
int running = 1;
|
||||||
|
int dragging = 0;
|
||||||
|
int drag_offset_x = 0;
|
||||||
|
int drag_offset_y = 0;
|
||||||
|
|
||||||
|
(void)height;
|
||||||
|
|
||||||
|
while (running != 0) {
|
||||||
|
u64 budget = 0ULL;
|
||||||
|
int handled = 0;
|
||||||
|
|
||||||
|
while (budget < 64ULL) {
|
||||||
|
cleonos_wm_event event;
|
||||||
|
ush_zero(&event, (u64)sizeof(event));
|
||||||
|
if (cleonos_sys_wm_poll_event(window_id, &event) == 0ULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = 1;
|
||||||
|
if (event.type == CLEONOS_WM_EVENT_KEY) {
|
||||||
|
if (event.arg0 == (u64)'q' || event.arg0 == (u64)'Q' || event.arg0 == 27ULL ||
|
||||||
|
event.arg0 == 13ULL) {
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (event.type == CLEONOS_WM_EVENT_MOUSE_BUTTON) {
|
||||||
|
u64 buttons = event.arg0;
|
||||||
|
u64 changed = event.arg1;
|
||||||
|
int local_x = ush_qrcode_u64_as_i32(event.arg2);
|
||||||
|
int local_y = ush_qrcode_u64_as_i32(event.arg3);
|
||||||
|
int left_changed = ((changed & 0x1ULL) != 0ULL) ? 1 : 0;
|
||||||
|
int left_down = ((buttons & 0x1ULL) != 0ULL) ? 1 : 0;
|
||||||
|
|
||||||
|
if (left_changed != 0) {
|
||||||
|
if (left_down == 0) {
|
||||||
|
dragging = 0;
|
||||||
|
} else if (ush_qrcode_close_hit(width, local_x, local_y) != 0) {
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
} else if (local_y >= 0 && local_y < USH_QRCODE_TITLE_H) {
|
||||||
|
dragging = 1;
|
||||||
|
drag_offset_x = local_x;
|
||||||
|
drag_offset_y = local_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (event.type == CLEONOS_WM_EVENT_MOUSE_MOVE && dragging != 0) {
|
||||||
|
cleonos_wm_move_req move_req;
|
||||||
|
x = ush_qrcode_u64_as_i32(event.arg0) - drag_offset_x;
|
||||||
|
y = ush_qrcode_u64_as_i32(event.arg1) - drag_offset_y;
|
||||||
|
move_req.window_id = window_id;
|
||||||
|
move_req.x = (u64)(i64)x;
|
||||||
|
move_req.y = (u64)(i64)y;
|
||||||
|
(void)cleonos_sys_wm_move(&move_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
budget++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (running == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled != 0) {
|
||||||
|
(void)cleonos_sys_yield();
|
||||||
|
} else {
|
||||||
|
(void)cleonos_sys_sleep_ticks(1ULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ush_qrcode_emit_window(const uint8_t qrcode[]) {
|
||||||
|
int qr_size = qrcodegen_getSize(qrcode);
|
||||||
|
cleonos_fb_info fb_info;
|
||||||
|
cleonos_wm_create_req create_req;
|
||||||
|
u64 old_tty;
|
||||||
|
u64 window_id;
|
||||||
|
int win_x;
|
||||||
|
int win_y;
|
||||||
|
int win_w;
|
||||||
|
int win_h;
|
||||||
|
|
||||||
|
if (qr_size <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ush_zero(&fb_info, (u64)sizeof(fb_info));
|
ush_zero(&fb_info, (u64)sizeof(fb_info));
|
||||||
if (cleonos_sys_fb_info(&fb_info) == 0ULL || fb_info.width == 0ULL || fb_info.height == 0ULL ||
|
if (cleonos_sys_fb_info(&fb_info) == 0ULL || fb_info.width == 0ULL || fb_info.height == 0ULL ||
|
||||||
fb_info.bpp != 32ULL) {
|
fb_info.bpp != 32ULL) {
|
||||||
ush_writeln("qrcode: framebuffer unavailable, fallback to ascii");
|
ush_writeln("qrcode: desktop unavailable, fallback to ascii");
|
||||||
ush_qrcode_emit_ascii(qrcode);
|
ush_qrcode_emit_ascii(qrcode);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_pixels_x = fb_info.width / side_modules;
|
ush_qrcode_choose_window_geometry(&fb_info, &win_x, &win_y, &win_w, &win_h);
|
||||||
module_pixels_y = fb_info.height / side_modules;
|
if (ush_qrcode_draw_window_canvas(qrcode, win_w, win_h) == 0) {
|
||||||
module_pixels = (module_pixels_x < module_pixels_y) ? module_pixels_x : module_pixels_y;
|
ush_writeln("qrcode: desktop window too small");
|
||||||
|
|
||||||
if (module_pixels == 0ULL) {
|
|
||||||
ush_writeln("qrcode: framebuffer too small");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_pixels_canvas_cap = (u64)USH_QRCODE_CANVAS_MAX / side_modules;
|
old_tty = cleonos_sys_tty_active();
|
||||||
if (module_pixels_canvas_cap == 0ULL) {
|
if (old_tty != USH_QRCODE_TTY_DISPLAY) {
|
||||||
|
(void)cleonos_sys_tty_switch(USH_QRCODE_TTY_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
create_req.x = (u64)(i64)win_x;
|
||||||
|
create_req.y = (u64)(i64)win_y;
|
||||||
|
create_req.width = (u64)(unsigned int)win_w;
|
||||||
|
create_req.height = (u64)(unsigned int)win_h;
|
||||||
|
create_req.flags = CLEONOS_WM_FLAG_TOPMOST;
|
||||||
|
window_id = cleonos_sys_wm_create(&create_req);
|
||||||
|
if (window_id == 0ULL) {
|
||||||
|
if (old_tty != USH_QRCODE_TTY_DISPLAY) {
|
||||||
|
(void)cleonos_sys_tty_switch(old_tty);
|
||||||
|
}
|
||||||
|
ush_writeln("qrcode: wm window create failed, fallback to ascii");
|
||||||
|
ush_qrcode_emit_ascii(qrcode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ush_qrcode_present_window(window_id, win_w, win_h) == 0) {
|
||||||
|
(void)cleonos_sys_wm_destroy(window_id);
|
||||||
|
if (old_tty != USH_QRCODE_TTY_DISPLAY) {
|
||||||
|
(void)cleonos_sys_tty_switch(old_tty);
|
||||||
|
}
|
||||||
|
ush_writeln("qrcode: wm present failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module_pixels > module_pixels_canvas_cap) {
|
(void)cleonos_sys_wm_set_focus(window_id);
|
||||||
module_pixels = module_pixels_canvas_cap;
|
ush_qrcode_window_loop(window_id, win_w, win_h, win_x, win_y);
|
||||||
}
|
(void)cleonos_sys_wm_destroy(window_id);
|
||||||
|
if (old_tty != USH_QRCODE_TTY_DISPLAY) {
|
||||||
if (ush_qrcode_build_canvas(qrcode, module_pixels, &side_pixels) == 0) {
|
(void)cleonos_sys_tty_switch(old_tty);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_w = side_pixels;
|
|
||||||
draw_h = side_pixels;
|
|
||||||
|
|
||||||
req.pixels_ptr = (u64)(void *)&ush_qrcode_canvas[0][0];
|
|
||||||
req.src_width = side_pixels;
|
|
||||||
req.src_height = side_pixels;
|
|
||||||
req.src_pitch_bytes = (u64)USH_QRCODE_CANVAS_MAX * 4ULL;
|
|
||||||
req.dst_x = (fb_info.width > draw_w) ? ((fb_info.width - draw_w) / 2ULL) : 0ULL;
|
|
||||||
req.dst_y = (fb_info.height > draw_h) ? ((fb_info.height - draw_h) / 2ULL) : 0ULL;
|
|
||||||
req.scale = 1ULL;
|
|
||||||
|
|
||||||
(void)cleonos_sys_fb_clear(USH_QRCODE_COLOR_LIGHT);
|
|
||||||
if (cleonos_sys_fb_blit(&req) == 0ULL) {
|
|
||||||
ush_writeln("qrcode: framebuffer blit failed");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -335,7 +636,7 @@ static int ush_cmd_qrcode(const char *arg) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ush_qrcode_emit_pixels(qrcode);
|
return ush_qrcode_emit_window(qrcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cleonos_app_main(void) {
|
int cleonos_app_main(void) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
static void ush_uwm_usage(void) {
|
static void ush_uwm_usage(void) {
|
||||||
ush_writeln("usage: uwm");
|
ush_writeln("usage: uwm");
|
||||||
ush_writeln("keys: q quit, tab focus, 1/2/3 restore, wasd/arrow move");
|
ush_writeln("keys: q quit, tab focus, 1/2/3 open apps, wasd/arrow move");
|
||||||
ush_writeln("keys: m minimize, x close, t pin top, +/- resize");
|
ush_writeln("keys: m minimize, x close, t pin top, +/- resize");
|
||||||
ush_writeln("mouse: drag titlebar, resize bottom-right, use taskbar/start");
|
ush_writeln("mouse: drag titlebar, resize bottom-right, use taskbar/start");
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ int ush_uwm_prepare_session(ush_uwm_session *sess) {
|
|||||||
|
|
||||||
sess->screen_w = (int)fb.width;
|
sess->screen_w = (int)fb.width;
|
||||||
sess->screen_h = (int)fb.height;
|
sess->screen_h = (int)fb.height;
|
||||||
sess->active_window = 0;
|
sess->active_window = -1;
|
||||||
sess->drag_window = -1;
|
sess->drag_window = -1;
|
||||||
sess->resize_window = -1;
|
sess->resize_window = -1;
|
||||||
sess->tty_before = cleonos_sys_tty_active();
|
sess->tty_before = cleonos_sys_tty_active();
|
||||||
@@ -179,7 +179,7 @@ int ush_uwm_prepare_session(ush_uwm_session *sess) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ush_uwm_init_window(&sess->windows[i], USH_UWM_KIND_APP, titles[i], subtitles[i], ush_uwm_clampi(x, 0, max_x),
|
ush_uwm_init_window(&sess->windows[i], USH_UWM_KIND_APP, titles[i], subtitles[i], ush_uwm_clampi(x, 0, max_x),
|
||||||
ush_uwm_clampi(y, USH_UWM_TOP_CLAMP_Y, max_y), base_w, base_h, accents[i], 0, 0);
|
ush_uwm_clampi(y, USH_UWM_TOP_CLAMP_Y, max_y), base_w, base_h, accents[i], 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ush_uwm_init_window(&sess->windows[USH_UWM_TASKBAR_INDEX], USH_UWM_KIND_TASKBAR, "TASKBAR", "", 0,
|
ush_uwm_init_window(&sess->windows[USH_UWM_TASKBAR_INDEX], USH_UWM_KIND_TASKBAR, "TASKBAR", "", 0,
|
||||||
@@ -200,9 +200,6 @@ int ush_uwm_prepare_session(ush_uwm_session *sess) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ush_uwm_start(ush_uwm_session *sess) {
|
int ush_uwm_start(ush_uwm_session *sess) {
|
||||||
int i;
|
|
||||||
int started = 0;
|
|
||||||
|
|
||||||
if (sess == (ush_uwm_session *)0) {
|
if (sess == (ush_uwm_session *)0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -211,23 +208,7 @@ int ush_uwm_start(ush_uwm_session *sess) {
|
|||||||
return ush_uwm_fail(sess, "uwm: taskbar create failed");
|
return ush_uwm_fail(sess, "uwm: taskbar create failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < (int)USH_UWM_APP_COUNT; i++) {
|
ush_uwm_toggle_start(sess);
|
||||||
if (ush_uwm_boot_window(sess, i) != 0) {
|
|
||||||
started++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (started == 0) {
|
|
||||||
return ush_uwm_fail(sess, "uwm: app window create failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = (int)USH_UWM_APP_COUNT - 1; i >= 0; i--) {
|
|
||||||
if (sess->windows[i].alive != 0) {
|
|
||||||
ush_uwm_set_active(sess, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ush_uwm_refresh_taskbar(sess);
|
ush_uwm_refresh_taskbar(sess);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
#include "uwm.h"
|
#include "uwm.h"
|
||||||
|
|
||||||
|
#define USH_UWM_FILE_EXPLORER_PATH "/shell/uwm/file_explorer.elf"
|
||||||
|
|
||||||
|
static int ush_uwm_launch_file_explorer(void) {
|
||||||
|
u64 pid = cleonos_sys_spawn_pathv(USH_UWM_FILE_EXPLORER_PATH, "", "LAUNCHED_BY=uwm");
|
||||||
|
|
||||||
|
return (pid != 0ULL && pid != (u64)-1) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ush_uwm_launch_or_restore_app(ush_uwm_session *sess, int index) {
|
||||||
|
if (sess == (ush_uwm_session *)0 || ush_uwm_app_index_valid(index) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
(void)ush_uwm_launch_file_explorer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ush_uwm_restore_window(sess, index);
|
||||||
|
}
|
||||||
|
|
||||||
static int ush_uwm_hit_close(const ush_uwm_window *win, int x, int y) {
|
static int ush_uwm_hit_close(const ush_uwm_window *win, int x, int y) {
|
||||||
return (win != (const ush_uwm_window *)0 && x >= win->w - USH_UWM_CONTROL_W && y >= 0 && y < USH_UWM_TITLE_H) ? 1
|
return (win != (const ush_uwm_window *)0 && x >= win->w - USH_UWM_CONTROL_W && y >= 0 && y < USH_UWM_TITLE_H) ? 1
|
||||||
: 0;
|
: 0;
|
||||||
@@ -77,7 +98,7 @@ static void ush_uwm_handle_key_event(ush_uwm_session *sess, u64 key, int *runnin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == (u64)'1' || key == (u64)'2' || key == (u64)'3') {
|
if (key == (u64)'1' || key == (u64)'2' || key == (u64)'3') {
|
||||||
ush_uwm_restore_window(sess, (int)(key - (u64)'1'));
|
ush_uwm_launch_or_restore_app(sess, (int)(key - (u64)'1'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +175,7 @@ static void ush_uwm_handle_taskbar_click(ush_uwm_session *sess, int local_x, int
|
|||||||
if (app->alive != 0 && app->minimized == 0 && sess->active_window == i) {
|
if (app->alive != 0 && app->minimized == 0 && sess->active_window == i) {
|
||||||
ush_uwm_minimize_window(sess, i);
|
ush_uwm_minimize_window(sess, i);
|
||||||
} else {
|
} else {
|
||||||
ush_uwm_restore_window(sess, i);
|
ush_uwm_launch_or_restore_app(sess, i);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -178,8 +199,8 @@ static void ush_uwm_handle_start_click(ush_uwm_session *sess, int local_x, int l
|
|||||||
int y = 78 + (i * 44);
|
int y = 78 + (i * 44);
|
||||||
|
|
||||||
if (local_x >= 66 && local_x < sess->windows[USH_UWM_START_INDEX].w - 16 && local_y >= y && local_y < y + 34) {
|
if (local_x >= 66 && local_x < sess->windows[USH_UWM_START_INDEX].w - 16 && local_y >= y && local_y < y + 34) {
|
||||||
ush_uwm_restore_window(sess, i);
|
|
||||||
ush_uwm_close_start(sess);
|
ush_uwm_close_start(sess);
|
||||||
|
ush_uwm_launch_or_restore_app(sess, i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ static void ush_uwm_render_taskbar(ush_uwm_session *sess) {
|
|||||||
|
|
||||||
if (app->closed != 0) {
|
if (app->closed != 0) {
|
||||||
bg = 0x001F1F1FU;
|
bg = 0x001F1F1FU;
|
||||||
fg = 0x007C7C7CU;
|
fg = 0x008F8F8FU;
|
||||||
} else if (app->minimized != 0) {
|
} else if (app->minimized != 0) {
|
||||||
bg = 0x002F2F2FU;
|
bg = 0x002F2F2FU;
|
||||||
} else if (sess->active_window == i) {
|
} else if (sess->active_window == i) {
|
||||||
|
|||||||
2
clks
2
clks
Submodule clks updated: 6b45f4805a...e56b4dfa85
@@ -75,6 +75,12 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
|
|
||||||
- `FS_MKDIR` / `FS_WRITE` / `FS_APPEND` / `FS_REMOVE` 仅允许 `/temp` 树下路径,或已挂载磁盘路径树下(默认挂载点通常为 `/temp/disk`)。
|
- `FS_MKDIR` / `FS_WRITE` / `FS_APPEND` / `FS_REMOVE` 仅允许 `/temp` 树下路径,或已挂载磁盘路径树下(默认挂载点通常为 `/temp/disk`)。
|
||||||
|
|
||||||
|
UserSafeController(USC)危险 syscall 确认:
|
||||||
|
|
||||||
|
- USC 拦截到危险 syscall 时仍支持“仅本次 / 本会话 / 永久 / 拒绝”四种结果。
|
||||||
|
- 如果内核窗口管理器已初始化且桌面 TTY 正在前台,确认请求会以置顶桌面弹窗显示;可点击按钮,也可按 `1/O`、`2/S`、`3/P`、`N/Esc/Enter` 选择。
|
||||||
|
- 如果当前不在桌面环境、键盘被禁用,或弹窗创建失败,则回退到原 TTY/串口确认流程。
|
||||||
|
|
||||||
`/proc` 虚拟目录(由 syscall 层动态导出):
|
`/proc` 虚拟目录(由 syscall 层动态导出):
|
||||||
|
|
||||||
- `/proc`:目录(children = `self`、`list`、以及全部 PID 名称)
|
- `/proc`:目录(children = `self`、`list`、以及全部 PID 名称)
|
||||||
|
|||||||
Reference in New Issue
Block a user