feat: expose drive labels to userspace, render in Files

This commit is contained in:
2026-04-22 07:45:33 +02:00
parent 0dfb3e8dbb
commit 6c2796f8bd
20 changed files with 261 additions and 38 deletions
+4
View File
@@ -122,4 +122,8 @@ namespace Montauk {
static int Sys_DriveList(int* outDrives, int maxEntries) { static int Sys_DriveList(int* outDrives, int maxEntries) {
return Fs::Vfs::VfsDriveList(outDrives, maxEntries); return Fs::Vfs::VfsDriveList(outDrives, maxEntries);
} }
static int Sys_DriveLabel(int driveNumber, char* outLabel, int maxLen) {
return Fs::Vfs::VfsDriveLabel(driveNumber, outLabel, maxLen);
}
}; };
+4
View File
@@ -209,6 +209,10 @@ namespace Montauk {
if ((int64_t)frame->arg2 < 0) return -1; if ((int64_t)frame->arg2 < 0) return -1;
if (!UserMemory::Range(frame->arg1, (uint64_t)frame->arg2 * sizeof(int), true)) return -1; if (!UserMemory::Range(frame->arg1, (uint64_t)frame->arg2 * sizeof(int), true)) return -1;
return (int64_t)Sys_DriveList((int*)frame->arg1, (int)frame->arg2); return (int64_t)Sys_DriveList((int*)frame->arg1, (int)frame->arg2);
case SYS_DRIVELABEL:
if ((int64_t)frame->arg3 <= 0) return -1;
if (!UserMemory::Range(frame->arg2, frame->arg3, true)) return -1;
return (int64_t)Sys_DriveLabel((int)frame->arg1, (char*)frame->arg2, (int)frame->arg3);
case SYS_TERMSCALE: case SYS_TERMSCALE:
return Sys_TermScale(frame->arg1, frame->arg2); return Sys_TermScale(frame->arg1, frame->arg2);
case SYS_RESOLVE: case SYS_RESOLVE:
+3
View File
@@ -222,6 +222,9 @@ namespace Montauk {
/* Input.hpp */ /* Input.hpp */
static constexpr uint64_t SYS_INPUT_WAIT = 123; static constexpr uint64_t SYS_INPUT_WAIT = 123;
/* Filesystem.hpp */
static constexpr uint64_t SYS_DRIVELABEL = 124;
static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024; static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024;
static constexpr uint32_t IPC_SIGNAL_READABLE = 1u << 0; static constexpr uint32_t IPC_SIGNAL_READABLE = 1u << 0;
+1
View File
@@ -65,6 +65,7 @@ namespace Fs {
Ramdisk::Delete, Ramdisk::Delete,
Ramdisk::Mkdir, Ramdisk::Mkdir,
Ramdisk::Rename, Ramdisk::Rename,
Ramdisk::GetLabel,
}; };
} }
+7
View File
@@ -1592,6 +1592,11 @@ namespace Fs::Ext2 {
// Template thunks — generate unique function pointers per instance // Template thunks — generate unique function pointers per instance
// ========================================================================= // =========================================================================
static const char* GetLabelImpl(int inst) {
if (inst < 0 || inst >= g_instanceCount || !g_instances[inst].active) return nullptr;
return g_instances[inst].volumeLabel[0] ? g_instances[inst].volumeLabel : nullptr;
}
template<int N> struct Thunks { template<int N> struct Thunks {
static int Open(const char* p) { return OpenImpl(N, p); } static int Open(const char* p) { return OpenImpl(N, p); }
static int Read(int h, uint8_t* b, uint64_t o, uint64_t s) { return ReadImpl(N, h, b, o, s); } static int Read(int h, uint8_t* b, uint64_t o, uint64_t s) { return ReadImpl(N, h, b, o, s); }
@@ -1603,6 +1608,7 @@ namespace Fs::Ext2 {
static int Delete(const char* p) { return DeleteImpl(N, p); } static int Delete(const char* p) { return DeleteImpl(N, p); }
static int Mkdir(const char* p) { return MkdirImpl(N, p); } static int Mkdir(const char* p) { return MkdirImpl(N, p); }
static int Rename(const char* o, const char* n) { return RenameImpl(N, o, n); } static int Rename(const char* o, const char* n) { return RenameImpl(N, o, n); }
static const char* GetLabel() { return GetLabelImpl(N); }
}; };
template<int N> template<int N>
@@ -1618,6 +1624,7 @@ namespace Fs::Ext2 {
Thunks<N>::Delete, Thunks<N>::Delete,
Thunks<N>::Mkdir, Thunks<N>::Mkdir,
Thunks<N>::Rename, Thunks<N>::Rename,
Thunks<N>::GetLabel,
}; };
} }
+10
View File
@@ -1748,6 +1748,14 @@ namespace Fs::Fat32 {
// Template thunks — generate unique function pointers per instance // Template thunks — generate unique function pointers per instance
// ========================================================================= // =========================================================================
static const char* GetLabelImpl(int inst) {
if (inst < 0 || inst >= g_instanceCount || !g_instances[inst].active) return nullptr;
const char* label = g_instances[inst].volumeLabel;
if (label[0] == '\0' || StrEqualNoCase(label, "NO NAME")) return nullptr;
return label;
}
template<int N> struct Thunks { template<int N> struct Thunks {
static int Open(const char* p) { return OpenImpl(N, p); } static int Open(const char* p) { return OpenImpl(N, p); }
static int Read(int h, uint8_t* b, uint64_t o, uint64_t s) { return ReadImpl(N, h, b, o, s); } static int Read(int h, uint8_t* b, uint64_t o, uint64_t s) { return ReadImpl(N, h, b, o, s); }
@@ -1759,6 +1767,7 @@ namespace Fs::Fat32 {
static int Delete(const char* p) { return DeleteImpl(N, p); } static int Delete(const char* p) { return DeleteImpl(N, p); }
static int Mkdir(const char* p) { return MkdirImpl(N, p); } static int Mkdir(const char* p) { return MkdirImpl(N, p); }
static int Rename(const char* o, const char* n) { return RenameImpl(N, o, n); } static int Rename(const char* o, const char* n) { return RenameImpl(N, o, n); }
static const char* GetLabel() { return GetLabelImpl(N); }
}; };
template<int N> template<int N>
@@ -1774,6 +1783,7 @@ namespace Fs::Fat32 {
Thunks<N>::Delete, Thunks<N>::Delete,
Thunks<N>::Mkdir, Thunks<N>::Mkdir,
Thunks<N>::Rename, Thunks<N>::Rename,
Thunks<N>::GetLabel,
}; };
} }
+4
View File
@@ -38,6 +38,10 @@ namespace Fs::Ramdisk {
return n; return n;
} }
const char* GetLabel() {
return "Ramdisk";
}
static bool StartsWith(const char* str, const char* prefix) { static bool StartsWith(const char* str, const char* prefix) {
while (*prefix) { while (*prefix) {
if (*str != *prefix) return false; if (*str != *prefix) return false;
+1
View File
@@ -35,6 +35,7 @@ namespace Fs::Ramdisk {
int Delete(const char* path); int Delete(const char* path);
int Mkdir(const char* path); int Mkdir(const char* path);
int Rename(const char* oldPath, const char* newPath); int Rename(const char* oldPath, const char* newPath);
const char* GetLabel();
int GetFileCount(); int GetFileCount();
} }
+32
View File
@@ -208,6 +208,38 @@ namespace Fs::Vfs {
return count; return count;
} }
int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen) {
if (outLabel == nullptr || maxLen <= 0) return -1;
outLabel[0] = '\0';
vfsLock.Acquire();
if (driveNumber < 0 || driveNumber >= MaxDrives || driveTable[driveNumber] == nullptr) {
vfsLock.Release();
return -1;
}
if (driveTable[driveNumber]->GetLabel == nullptr) {
vfsLock.Release();
return 0;
}
const char* label = driveTable[driveNumber]->GetLabel();
if (label == nullptr || label[0] == '\0') {
vfsLock.Release();
return 0;
}
int copied = 0;
while (label[copied] != '\0' && copied < maxLen - 1) {
outLabel[copied] = label[copied];
copied++;
}
outLabel[copied] = '\0';
vfsLock.Release();
return copied;
}
int VfsRename(const char* oldPath, const char* newPath) { int VfsRename(const char* oldPath, const char* newPath) {
int oldDrive, newDrive; int oldDrive, newDrive;
const char* oldLocal; const char* oldLocal;
+2
View File
@@ -28,6 +28,7 @@ namespace Fs::Vfs {
int (*Delete)(const char* path); int (*Delete)(const char* path);
int (*Mkdir)(const char* path); int (*Mkdir)(const char* path);
int (*Rename)(const char* oldPath, const char* newPath); int (*Rename)(const char* oldPath, const char* newPath);
const char* (*GetLabel)();
}; };
void Initialize(); void Initialize();
@@ -48,5 +49,6 @@ namespace Fs::Vfs {
// Returns number of registered drives, fills outDrives[] with their indices // Returns number of registered drives, fills outDrives[] with their indices
int VfsDriveList(int* outDrives, int maxEntries); int VfsDriveList(int* outDrives, int maxEntries);
int VfsDriveLabel(int driveNumber, char* outLabel, int maxLen);
} }
+1
View File
@@ -157,6 +157,7 @@ namespace Montauk {
static constexpr uint64_t SYS_CLIPBOARD_GET_TEXT = 121; static constexpr uint64_t SYS_CLIPBOARD_GET_TEXT = 121;
static constexpr uint64_t SYS_CLIPBOARD_CLEAR = 122; static constexpr uint64_t SYS_CLIPBOARD_CLEAR = 122;
static constexpr uint64_t SYS_INPUT_WAIT = 123; static constexpr uint64_t SYS_INPUT_WAIT = 123;
static constexpr uint64_t SYS_DRIVELABEL = 124;
static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024; static constexpr uint32_t CLIPBOARD_MAX_TEXT_BYTES = 256 * 1024;
+1
View File
@@ -92,6 +92,7 @@ extern "C" {
#define MTK_SYS_FMKDIR 78 #define MTK_SYS_FMKDIR 78
#define MTK_SYS_FRENAME 94 #define MTK_SYS_FRENAME 94
#define MTK_SYS_DRIVELIST 79 #define MTK_SYS_DRIVELIST 79
#define MTK_SYS_DRIVELABEL 124
#define MTK_SYS_AUDIOOPEN 80 #define MTK_SYS_AUDIOOPEN 80
#define MTK_SYS_AUDIOCLOSE 81 #define MTK_SYS_AUDIOCLOSE 81
#define MTK_SYS_AUDIOWRITE 82 #define MTK_SYS_AUDIOWRITE 82
+3
View File
@@ -161,6 +161,9 @@ namespace montauk {
inline int drivelist(int* outDrives, int max) { inline int drivelist(int* outDrives, int max) {
return (int)syscall2(Montauk::SYS_DRIVELIST, (uint64_t)outDrives, (uint64_t)max); return (int)syscall2(Montauk::SYS_DRIVELIST, (uint64_t)outDrives, (uint64_t)max);
} }
inline int drivelabel(int drive, char* outLabel, int maxLen) {
return (int)syscall3(Montauk::SYS_DRIVELABEL, (uint64_t)drive, (uint64_t)outLabel, (uint64_t)maxLen);
}
// Memory // Memory
inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); } inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); }
@@ -117,11 +117,10 @@ void filemanager_on_mouse(Window* win, MouseEvent& ev) {
if (local_y >= list_y && local_x < cw - FM_SCROLLBAR_W) { if (local_y >= list_y && local_x < cw - FM_SCROLLBAR_W) {
int cols = (cw - FM_SCROLLBAR_W) / FM_GRID_CELL_W; int cols = (cw - FM_SCROLLBAR_W) / FM_GRID_CELL_W;
if (cols < 1) cols = 1; if (cols < 1) cols = 1;
int col = local_x / FM_GRID_CELL_W; int rel_y = local_y - list_y + fm->scrollbar.scroll_offset;
int row = (local_y - list_y + fm->scrollbar.scroll_offset) / FM_GRID_CELL_H; int clicked_idx = filemanager_grid_index_at(fm, cols, local_x, rel_y);
int clicked_idx = row * cols + col;
if (clicked_idx >= 0 && clicked_idx < fm->entry_count && col < cols) { if (clicked_idx >= 0 && clicked_idx < fm->entry_count) {
uint64_t now = montauk::get_milliseconds(); uint64_t now = montauk::get_milliseconds();
if (fm->last_click_item == clicked_idx && if (fm->last_click_item == clicked_idx &&
@@ -179,10 +178,9 @@ void filemanager_on_mouse(Window* win, MouseEvent& ev) {
if (local_x < cw - FM_SCROLLBAR_W) { if (local_x < cw - FM_SCROLLBAR_W) {
int cols = (cw - FM_SCROLLBAR_W) / FM_GRID_CELL_W; int cols = (cw - FM_SCROLLBAR_W) / FM_GRID_CELL_W;
if (cols < 1) cols = 1; if (cols < 1) cols = 1;
int col = local_x / FM_GRID_CELL_W; int rel_y = local_y - list_y + fm->scrollbar.scroll_offset;
int row = (local_y - list_y + fm->scrollbar.scroll_offset) / FM_GRID_CELL_H; int idx = filemanager_grid_index_at(fm, cols, local_x, rel_y);
int idx = row * cols + col; if (idx >= 0 && idx < fm->entry_count) {
if (idx >= 0 && idx < fm->entry_count && col < cols) {
target_idx = idx; target_idx = idx;
fm->selected = idx; fm->selected = idx;
} }
@@ -73,6 +73,7 @@ inline constexpr int FM_ITEM_H = 24;
inline constexpr int FM_SCROLLBAR_W = 12; inline constexpr int FM_SCROLLBAR_W = 12;
inline constexpr int FM_GRID_CELL_W = 80; inline constexpr int FM_GRID_CELL_W = 80;
inline constexpr int FM_GRID_CELL_H = 80; inline constexpr int FM_GRID_CELL_H = 80;
inline constexpr int FM_GRID_CELL_H_WRAPPED = 92;
inline constexpr int FM_GRID_ICON = 48; inline constexpr int FM_GRID_ICON = 48;
inline constexpr int FM_GRID_PAD = 4; inline constexpr int FM_GRID_PAD = 4;
@@ -151,6 +152,11 @@ void filemanager_commit_pathbar(FileManagerState* fm);
void filemanager_open_entry(FileManagerState* fm, int idx); void filemanager_open_entry(FileManagerState* fm, int idx);
int filemanager_grid_row_height(FileManagerState* fm, int row, int cols);
int filemanager_grid_row_y(FileManagerState* fm, int row, int cols);
int filemanager_grid_content_height(FileManagerState* fm, int cols);
int filemanager_grid_index_at(FileManagerState* fm, int cols, int x, int rel_y);
void filemanager_draw_header(Canvas& c, FileManagerState* fm, Color toolbar_color, Color btn_bg); void filemanager_draw_header(Canvas& c, FileManagerState* fm, Color toolbar_color, Color btn_bg);
void filemanager_on_draw(Window* win, Framebuffer& fb); void filemanager_on_draw(Window* win, Framebuffer& fb);
void filemanager_on_mouse(Window* win, MouseEvent& ev); void filemanager_on_mouse(Window* win, MouseEvent& ev);
@@ -85,6 +85,12 @@ void filemanager_read_drives(FileManagerState* fm) {
char label[64]; char label[64];
montauk::strcpy(label, "Drive "); montauk::strcpy(label, "Drive ");
str_append(label, probe, 64); str_append(label, probe, 64);
char volume_label[64];
if (montauk::drivelabel(d, volume_label, 64) > 0 && volume_label[0] != '\0') {
str_append(label, " [", 64);
str_append(label, volume_label, 64);
str_append(label, "]", 64);
}
montauk::strncpy(fm->entry_names[i], label, 63); montauk::strncpy(fm->entry_names[i], label, 63);
fm->entry_types[i] = 3; // drive fm->entry_types[i] = 3; // drive
fm->entry_sizes[i] = 0; fm->entry_sizes[i] = 0;
+165 -30
View File
@@ -8,6 +8,155 @@
namespace filemanager { namespace filemanager {
static bool label_break_char(char ch) {
return ch == ' ' || ch == '-' || ch == '_' || ch == '/';
}
static void copy_label_range(char* dst, int dst_max, const char* src, int start, int end) {
if (!dst || dst_max <= 0) return;
while (start < end && src[start] == ' ') start++;
while (end > start && src[end - 1] == ' ') end--;
int out = 0;
for (int i = start; i < end && out < dst_max - 1; i++) {
dst[out++] = src[i];
}
dst[out] = '\0';
}
static int fitted_prefix_len(const char* src, int max_w, int max_len) {
char tmp[128];
int best = 0;
int limit = max_len < 127 ? max_len : 127;
for (int len = 1; len <= limit; len++) {
copy_label_range(tmp, sizeof(tmp), src, 0, len);
if (text_width(tmp) > max_w) break;
best = len;
}
return best > 0 ? best : 1;
}
static void fit_label_with_ellipsis(char* dst, int dst_max, const char* src, int max_w) {
montauk::strncpy(dst, src, dst_max);
if (text_width(dst) <= max_w) return;
int ellipsis_w = text_width("...");
int len = montauk::slen(dst);
while (len > 0) {
dst[len] = '\0';
if (text_width(dst) + ellipsis_w <= max_w) break;
len--;
}
if (len > dst_max - 4) len = dst_max - 4;
if (len < 0) len = 0;
dst[len] = '.';
dst[len + 1] = '.';
dst[len + 2] = '.';
dst[len + 3] = '\0';
}
static void build_grid_label_lines(const char* name, int max_w,
char* line1, int line1_max,
char* line2, int line2_max) {
line1[0] = '\0';
line2[0] = '\0';
if (text_width(name) <= max_w) {
montauk::strncpy(line1, name, line1_max);
return;
}
int nlen = montauk::slen(name);
int break_end = -1;
int break_next = -1;
for (int i = 0; i < nlen - 1; i++) {
if (!label_break_char(name[i])) continue;
int end = (name[i] == ' ') ? i : i + 1;
int next = i + 1;
char candidate[128];
copy_label_range(candidate, sizeof(candidate), name, 0, end);
if (candidate[0] != '\0' && text_width(candidate) <= max_w) {
break_end = end;
break_next = next;
}
}
if (break_end < 0) {
break_end = fitted_prefix_len(name, max_w, nlen);
break_next = break_end;
}
copy_label_range(line1, line1_max, name, 0, break_end);
fit_label_with_ellipsis(line2, line2_max, name + break_next, max_w);
}
static void draw_centered_grid_label(Canvas& c, int cell_x, int y, const char* label, Color color) {
int tw = text_width(label);
int tx = cell_x + (FM_GRID_CELL_W - tw) / 2;
if (tx < cell_x + 2) tx = cell_x + 2;
c.text(tx, y, label, color);
}
int filemanager_grid_row_height(FileManagerState* fm, int row, int cols) {
if (!fm || cols <= 0 || row < 0) return FM_GRID_CELL_H;
int start = row * cols;
int end = start + cols;
if (end > fm->entry_count) end = fm->entry_count;
int max_w = FM_GRID_CELL_W - 4;
for (int i = start; i < end; i++) {
if (text_width(fm->entry_names[i]) > max_w) {
return FM_GRID_CELL_H_WRAPPED;
}
}
return FM_GRID_CELL_H;
}
int filemanager_grid_row_y(FileManagerState* fm, int row, int cols) {
int y = 0;
for (int r = 0; r < row; r++) {
y += filemanager_grid_row_height(fm, r, cols);
}
return y;
}
int filemanager_grid_content_height(FileManagerState* fm, int cols) {
if (!fm || cols <= 0) return 0;
int rows = (fm->entry_count + cols - 1) / cols;
int h = 0;
for (int r = 0; r < rows; r++) {
h += filemanager_grid_row_height(fm, r, cols);
}
return h;
}
int filemanager_grid_index_at(FileManagerState* fm, int cols, int x, int rel_y) {
if (!fm || cols <= 0 || x < 0 || rel_y < 0) return -1;
int col = x / FM_GRID_CELL_W;
if (col < 0 || col >= cols) return -1;
int rows = (fm->entry_count + cols - 1) / cols;
int row_y = 0;
for (int row = 0; row < rows; row++) {
int row_h = filemanager_grid_row_height(fm, row, cols);
if (rel_y < row_y + row_h) {
int idx = row * cols + col;
return idx < fm->entry_count ? idx : -1;
}
row_y += row_h;
}
return -1;
}
void filemanager_draw_header(Canvas& c, FileManagerState* fm, Color toolbar_color, Color btn_bg) { void filemanager_draw_header(Canvas& c, FileManagerState* fm, Color toolbar_color, Color btn_bg) {
DesktopState* ds = fm->desktop; DesktopState* ds = fm->desktop;
@@ -133,8 +282,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
int list_h = c.h - list_y; int list_h = c.h - list_y;
int cols = (c.w - FM_SCROLLBAR_W) / FM_GRID_CELL_W; int cols = (c.w - FM_SCROLLBAR_W) / FM_GRID_CELL_W;
if (cols < 1) cols = 1; if (cols < 1) cols = 1;
int rows = (fm->entry_count + cols - 1) / cols; int content_h = filemanager_grid_content_height(fm, cols);
int content_h = rows * FM_GRID_CELL_H;
// Update scrollbar // Update scrollbar
fm->scrollbar.bounds = {c.w - FM_SCROLLBAR_W, list_y, FM_SCROLLBAR_W, list_h}; fm->scrollbar.bounds = {c.w - FM_SCROLLBAR_W, list_y, FM_SCROLLBAR_W, list_h};
@@ -145,15 +293,16 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
int col = i % cols; int col = i % cols;
int row = i / cols; int row = i / cols;
int cell_x = col * FM_GRID_CELL_W; int cell_x = col * FM_GRID_CELL_W;
int cell_y = list_y + row * FM_GRID_CELL_H - fm->scrollbar.scroll_offset; int row_h = filemanager_grid_row_height(fm, row, cols);
int cell_y = list_y + filemanager_grid_row_y(fm, row, cols) - fm->scrollbar.scroll_offset;
// Skip if entirely off-screen // Skip if entirely off-screen
if (cell_y + FM_GRID_CELL_H <= list_y || cell_y >= c.h) continue; if (cell_y + row_h <= list_y || cell_y >= c.h) continue;
// Selection highlight // Selection highlight
if (i == fm->selected) { if (i == fm->selected) {
int sy = gui_max(cell_y, list_y); int sy = gui_max(cell_y, list_y);
int sh = gui_min(cell_y + FM_GRID_CELL_H, c.h) - sy; int sh = gui_min(cell_y + row_h, c.h) - sy;
int sw = gui_min(FM_GRID_CELL_W, c.w - FM_SCROLLBAR_W - cell_x); int sw = gui_min(FM_GRID_CELL_W, c.w - FM_SCROLLBAR_W - cell_x);
if (sh > 0 && sw > 0) if (sh > 0 && sw > 0)
c.fill_rect(cell_x, sy, sw, sh, colors::MENU_HOVER); c.fill_rect(cell_x, sy, sw, sh, colors::MENU_HOVER);
@@ -217,35 +366,21 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
c.vline(cx, ty, system_font_height(), colors::ACCENT); c.vline(cx, ty, system_font_height(), colors::ACCENT);
} }
} else { } else {
// Truncate by pixel width so names never overflow cells // Prefer two grid label rows before truncating.
int max_w = FM_GRID_CELL_W - 4; int max_w = FM_GRID_CELL_W - 4;
const char* name = fm->entry_names[i]; const char* name = fm->entry_names[i];
int nlen = montauk::slen(name); char line1[128];
char label[64]; char line2[128];
montauk::strncpy(label, name, 63); build_grid_label_lines(name, max_w, line1, sizeof(line1), line2, sizeof(line2));
if (text_width(label) > max_w && nlen > 3) {
int ellipsis_w = text_width("...");
int final_len = nlen;
while (final_len > 1) {
label[final_len] = '\0';
int w = text_width(label);
if (w + ellipsis_w <= max_w) break;
final_len--;
}
if (final_len > 60) final_len = 60;
label[final_len] = '.';
label[final_len + 1] = '.';
label[final_len + 2] = '.';
label[final_len + 3] = '\0';
}
int tw = text_width(label);
int tx = cell_x + (FM_GRID_CELL_W - tw) / 2;
if (tx < cell_x) tx = cell_x;
int ty = icon_y + FM_GRID_ICON + 2; int ty = icon_y + FM_GRID_ICON + 2;
if (ty >= list_y && ty + system_font_height() <= c.h) int fh = system_font_height();
c.text(tx, ty, label, colors::TEXT_COLOR); if (ty >= list_y && ty + fh <= c.h) {
draw_centered_grid_label(c, cell_x, ty, line1, colors::TEXT_COLOR);
}
if (line2[0] != '\0' && ty + fh >= list_y && ty + fh * 2 <= c.h) {
draw_centered_grid_label(c, cell_x, ty + fh, line2, colors::TEXT_COLOR);
}
} }
} }
} else { } else {
+1
View File
@@ -57,6 +57,7 @@ namespace Montauk {
static constexpr uint64_t SYS_FDELETE = 77; static constexpr uint64_t SYS_FDELETE = 77;
static constexpr uint64_t SYS_FMKDIR = 78; static constexpr uint64_t SYS_FMKDIR = 78;
static constexpr uint64_t SYS_DRIVELIST = 79; static constexpr uint64_t SYS_DRIVELIST = 79;
static constexpr uint64_t SYS_DRIVELABEL = 124;
static constexpr uint64_t SYS_TERMSCALE = 43; static constexpr uint64_t SYS_TERMSCALE = 43;
static constexpr uint64_t SYS_RESOLVE = 44; static constexpr uint64_t SYS_RESOLVE = 44;
static constexpr uint64_t SYS_GETRANDOM = 45; static constexpr uint64_t SYS_GETRANDOM = 45;
+1
View File
@@ -91,6 +91,7 @@ extern "C" {
#define MTK_SYS_FMKDIR 78 #define MTK_SYS_FMKDIR 78
#define MTK_SYS_FRENAME 94 #define MTK_SYS_FRENAME 94
#define MTK_SYS_DRIVELIST 79 #define MTK_SYS_DRIVELIST 79
#define MTK_SYS_DRIVELABEL 124
#define MTK_SYS_AUDIOOPEN 80 #define MTK_SYS_AUDIOOPEN 80
#define MTK_SYS_AUDIOCLOSE 81 #define MTK_SYS_AUDIOCLOSE 81
#define MTK_SYS_AUDIOWRITE 82 #define MTK_SYS_AUDIOWRITE 82
@@ -152,6 +152,9 @@ namespace montauk {
inline int drivelist(int* outDrives, int max) { inline int drivelist(int* outDrives, int max) {
return (int)syscall2(Montauk::SYS_DRIVELIST, (uint64_t)outDrives, (uint64_t)max); return (int)syscall2(Montauk::SYS_DRIVELIST, (uint64_t)outDrives, (uint64_t)max);
} }
inline int drivelabel(int drive, char* outLabel, int maxLen) {
return (int)syscall3(Montauk::SYS_DRIVELABEL, (uint64_t)drive, (uint64_t)outLabel, (uint64_t)maxLen);
}
// Memory // Memory
inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); } inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); }