文件浏览器

This commit is contained in:
2026-04-26 02:16:02 +08:00
parent 5bdd763fc8
commit a4b606505f
8 changed files with 1534 additions and 102 deletions

View File

@@ -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}"

File diff suppressed because it is too large Load Diff

View File

@@ -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) {

View File

@@ -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;
} }

View File

@@ -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;
} }
} }

View File

@@ -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

Submodule clks updated: 6b45f4805a...e56b4dfa85

View File

@@ -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`)。
UserSafeControllerUSC危险 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 名称)