Author SHA1 Message Date
Leency 9ea9373547 unimg: make labels shorter and more common 2026-06-09 23:26:50 +03:00
Leency 241c30150a fs: fix that makes real_dir_exists() optional to include 2026-06-09 23:25:24 +03:00
Burer 7157b87e2c apps/unimg: fix build, optimization
- change all line endings to CRLF
- remove redundant kolibri.h include
2026-06-09 21:28:24 +03:00
Burer c6ed4b30b3 apps/unimg: add russian localization 2026-06-09 19:12:50 +03:00
Burer 895f37f77b apps/unimg: harden extraction, fix typos
- extract_file: bounds-check src, clamp to size
- skip reserved clusters (cluster >= 2)
- malloc: notify and skip on failure
- fix typos: claster - >cluster, Bytest -> Bytes
- call make_parent_dirs once, not per file
2026-06-09 19:12:49 +03:00
Leency ce67c7e929 upd descr 2026-06-09 16:46:38 +03:00
Leency 108e9f3d3a fix minisprintf() 2026-06-09 16:40:37 +03:00
Leency bc07b4a9f2 unimg:
- original version by Boppan (Magomed Kostoev) is rewritten to C--
- clean code
- now handle any image and sector size, not just kolibri.img
- fit into 2 kb (old version was 3.6 kb)
2026-06-09 16:38:01 +03:00
LeencyandBurer 275ee51ac4 apps/webview: update to 3.98 (#474)
- proper fix of line break
- new refresh / stop icons
- more comfortable debug mode
- remove old comments from code
- fix very old issue with text overlapping
-  line break on '-'

---------

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#474
Co-authored-by: leency <lipatov.kiril@gmail.com>
Co-committed-by: leency <lipatov.kiril@gmail.com>
2026-06-06 12:38:59 +00:00
LeencyandBurer b99f56c493 mousecfg: fix mouse clicks were not shown (#462)
Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#462
Co-authored-by: leency <lipatov.kiril@gmail.com>
Co-committed-by: leency <lipatov.kiril@gmail.com>
2026-06-02 11:56:29 +00:00
LeencyandBurer 72393db48e apps/app_plus: fix opening opendial, better warning window (#460)
## app_plus: fix calling opendial and rework floppy-mode warning window

- Fix: bump MEMSIZE 40K => 60K so the Open file dialog starts.
- UI: drop the fake dir-listing mockup for a single icon + clearer text; remove unused SCRX/SCRY/kolibrios_dirs.
- UI: reposition header/description/buttons to the new CONX/CONY layout.
- Text: rewrite RU+EN warning - explain floppy mode and how to mount /kolibrios.
- Review: fix CONY comment + English grammar.

---------

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#460
Co-authored-by: leency <lipatov.kiril@gmail.com>
Co-committed-by: leency <lipatov.kiril@gmail.com>
2026-06-02 08:57:26 +00:00
LeencyandBurer c391d7ba48 apps/webview: update test.htm, various bugfixes and improvements (#459)
## WebView 3.97

- Fix: closing `</font>` pops `text_colors` by its own count, not `bg_colors` — no more dropping the default text color (`set_style.h`).
- Fix: `_cache::clear()` also resets `current_type` and `current_charset` (`cache.h`).
- Feature: `<li>` inside `<nav>` is rendered inline, separated by a single space (`set_style.h`).
- Cleanup: remove dead `src = …` assignments in View Source; `<font>` counting reads `src_orig` directly, behavior unchanged (`show_src.h`).
- Chore: bump version to `WebView 3.97` (`const.h`).
- Content: update test/home pages, add a hidden Easter-egg link to the test page (`res/test.htm`, `res/homepage_*.htm`).

---------

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: KolibriOS/kolibrios#459
Co-authored-by: leency <lipatov.kiril@gmail.com>
Co-committed-by: leency <lipatov.kiril@gmail.com>
2026-06-01 16:59:57 +00:00
BurerandLeency 8534576857 apps/pixie: auto-download ac97snd backend if it is missing (#454)
If the ac97snd player fails to start, download it from builds.kolibrios.org
to /sys/media/ac97snd, wait for the downloader process to finish (polling
GetProcessSlot with a timeout), then retry. Notify the user if it still fails.

Depends on the downloader "URL|/save/path" support.

Co-authored-by: Burer <burer@kolibrios.org>

---------

Co-authored-by: Kiril Lipatov <lipatov.kiril@gmail.com>
Reviewed-on: KolibriOS/kolibrios#454
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Kiril Lipatov <lipatov.kiril@gmail.com>
2026-06-01 10:12:27 +00:00
BurerandLeency e4a9fc43d2 apps/dl: support explicit save path argument, change speed test URL (#453)
Add a "URL|/save/path" syntax so callers can download a file to a specific
destination instead of the default save dir (used by pixie to fetch the
ac97snd backend). With an explicit path, SaveFile overwrites it directly and
skips the auto-rename loop, which would otherwise recurse forever on a fixed
existing path.

Also point URL_SPEED_TEST (-test) at a working mirror.

Co-authored-by: Burer <burer@kolibrios.org>
---------

Co-authored-by: Kiril Lipatov <lipatov.kiril@gmail.com>
Reviewed-on: KolibriOS/kolibrios#453
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Kiril Lipatov <lipatov.kiril@gmail.com>
2026-06-01 10:12:03 +00:00
13 changed files with 591 additions and 137 deletions

No files matched your search

+36 -53
View File
@@ -1,6 +1,5 @@
#define MEMSIZE 1024*40
#include "..\lib\strings.h"
#include "..\lib\mem.h"
#define MEMSIZE 1024*60
#include "..\lib\gui.h"
#include "..\lib\obj\proc_lib.h"
#include "..\lib\patterns\simple_open_dialog.h"
@@ -15,9 +14,8 @@
#define WINW 570
#define WINH 300
#define CONX 30 //content X pos
#define SCRX WINW-180
#define SCRY 20
#define CONX 28 //content X pos
#define CONY 25 //content Y pos
char default_dir[] = "/sys";
od_filter filter2;
@@ -34,29 +32,28 @@ od_filter filter2;
//===================================================//
#ifdef LANG_RUS
?define WINDOW_TITLE_TEXT "Внимание! Это важно."
?define CONTENT_HEADER_TEXT "ПАПКА /KOLIBRIOS/ НЕ НАЙДЕНА"
?define DESCRIPTION_TEXT "Попробуйте найти ее самостоятельно.
Содержимое искомой папки показано на
картинке справа. В случае неверно
выбранной папки требуется выполнить
перезагрузку ПК и попробовать снова."
?define WINDOW_TITLE_TEXT "Внимание!"
?define CONTENT_HEADER_TEXT "KolibriOS работает в режиме дискеты"
?define DESCRIPTION_TEXT "Многие приложения сейчас недоступны.
Причина в том, что не смонтирован дополнительный системный
каталог. Но вы можете найти и задать его вручную. Его название
'kolibrios'. Вы также можете загрузить latest-dirstr.7z через
WebView и найти его внутри."
?define MANUALLY_BUTTON_TEXT "Указать папку /kolibrios/..."
?define OPEN_ANYWAY_BUTTON_TEXT "Запустить APP+ (некоторые программы будут недоступны)"
#else
?define WINDOW_TITLE_TEXT "Warning! It's important."
?define CONTENT_HEADER_TEXT "/KOLIBRIOS/ IS NOT MOUNTED"
?define DESCRIPTION_TEXT "Try to find it manually. It should look
like image on the right.
Note: this action can be done only once
per 1 session of the OS running. If you
will choose the wrong folder then you
need to reboot a system to try again."
?define MANUALLY_BUTTON_TEXT "Choose /kolibrios/ folder..."
?define OPEN_ANYWAY_BUTTON_TEXT "Open APP+ anyway (some programs won't be available) "
#endif
?define WINDOW_TITLE_TEXT "Warning!"
?define CONTENT_HEADER_TEXT "KolibriOS is running in floppy mode"
?define DESCRIPTION_TEXT "A lot of apps aren't available.
char kolibrios_dirs[] = "..\0 3D \0demos \0develop\0drivers\0emul \0games \0grafx2";
The reason is that additional system directory is not mounted.
But you can find and set it manually. Its name is 'kolibrios'.
You can also download latest-dirstr.7z via WebView and find
it inside."
?define MANUALLY_BUTTON_TEXT "Choose /kolibrios/ folder..."
?define OPEN_ANYWAY_BUTTON_TEXT "Open APP+ anyway (some programs won't be available)"
#endif
//===================================================//
// //
@@ -104,38 +101,22 @@ void draw_window()
{
sc.get();
DefineAndDrawWindow(screen.w-WINW/2, 100, WINW, WINH+skin_h, 0x34, sc.work, WINDOW_TITLE_TEXT,0);
WriteTextB(CONX+2,SCRY+2,0x81,MixColors(sc.work, 0xB92234,220),CONTENT_HEADER_TEXT);
WriteTextB(CONX,SCRY,0x81,0xB92234,CONTENT_HEADER_TEXT);
draw_screen();
WriteTextLines(CONX,SCRY+50,0x90,sc.work_text,DESCRIPTION_TEXT,20);
DrawButtons();
}
void draw_screen()
{
char i;
int icon_n=1;
DrawRectangle(WINW-180-1,SCRY-1, 145+1,170+1, sc.line);
DrawBar(SCRX,SCRY,145,170,0xFFFfff);
DrawBar(SCRX+25,SCRY+5,144-25,20,0xBBDDFF);
for (i=0; i<8; i++) {
draw_icon_16(SCRX+5, i*20+SCRY+5, icon_n);
WriteText(SCRX+27, i*20+SCRY+11, 0x80, 0, i*8 + #kolibrios_dirs);
icon_n = 0;
}
draw_icon_16w(CONX+2, CONY-3, 5);
WriteTextB(CONX+27+2,CONY+2,0x81,MixColors(sc.work, 0xB92234,220),CONTENT_HEADER_TEXT);
WriteTextB(CONX+27,CONY,0x81,0xB92234,CONTENT_HEADER_TEXT);
WriteTextLines(CONX,CONY+42,0x90,sc.work_text,DESCRIPTION_TEXT,20);
DrawButtons();
}
void DrawButtons()
{
DrawStandartCaptButton(CONX, WINH-80, BTN_MANUAL_SEARCH, MANUALLY_BUTTON_TEXT);
DrawStandartCaptButton(CONX, WINH-42, BTN_OPEN_ANYWAY, OPEN_ANYWAY_BUTTON_TEXT);
//DrawCaptButton(CONX, WINH-80, 300, 25, BTN_MANUAL_SEARCH, sc.button, sc.button_text, MANUALLY_BUTTON_TEXT);
//DrawCaptButton(CONX, WINH-42, 500, 25, BTN_OPEN_ANYWAY, sc.button, sc.button_text, OPEN_ANYWAY_BUTTON_TEXT);
DrawStandartCaptButton(CONX, WINH-CONY-58, BTN_MANUAL_SEARCH, MANUALLY_BUTTON_TEXT);
DrawStandartCaptButton(CONX, WINH-CONY-22, BTN_OPEN_ANYWAY, OPEN_ANYWAY_BUTTON_TEXT);
}
void CheckKosMounted()
{
if (dir_exists("/kolibrios"))
if (dir_exists("/kolibrios"))
{
if (file_exists(APP_PLUS_INI_PATH)) EventOpenApp();
ExitProcess();
@@ -158,13 +139,13 @@ void EventManualSearch()
OpenDialog_start stdcall (#o_dialog);
if (o_dialog.status) SetAdditionalSystemDirectory("kolibrios", #openfile_path+1);
pause(3);
CheckKosMounted();
CheckKosMounted();
}
void EventOpenApp()
{
if (RunProgram("/sys/syspanel", APP_PLUS_INI_PATH) < 0) {
notify("'App+ can not be started because\n/sys/syspanel does not exists' -E");
notify("'App+ cannot start because\n/sys/syspanel does not exist' -E");
}
}
@@ -172,8 +153,10 @@ void EventButton(dword id)
{
if (id==CLOSE_BTN) ExitProcess();
else if (id==BTN_MANUAL_SEARCH) EventManualSearch();
else if (id==BTN_OPEN_ANYWAY) { EventOpenApp(); ExitProcess(); }
else if (id==BTN_OPEN_ANYWAY) {
EventOpenApp();
ExitProcess();
}
}
stop:
+7 -14
View File
@@ -22,8 +22,9 @@ void TWebBrowser::RenderLine(dword _line)
zoom = list.font_w / BASIC_CHAR_W;
//there is some shit happens!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (pw > draw_w + BODY_MARGIN) {
//debugln("shit");
if (debug_mode) && (pw > draw_w + BODY_MARGIN) {
debugln("anomaly");
debugln(_line);
}
if (debug_mode) {
@@ -80,14 +81,12 @@ void TWebBrowser::RenderTextbuf()
//Yes, we do. Lets calculate where...
br = len;
//debugln(" \\n");
//Is a new line fits in the maximum line width?
if (br * list.font_w + draw_x - left_gap >= draw_w) {
br = draw_w - draw_x / list.font_w;
br = draw_w - draw_x + left_gap - BODY_MARGIN / list.font_w;
if (br < 0) br = 0;
while(br) {
if (ESBYTE[lbp + br]==' ') {
if (ESBYTE[lbp + br]==' ') || (ESBYTE[lbp + br]=='-') {
if (br < len) br++;
break;
}
@@ -96,15 +95,10 @@ void TWebBrowser::RenderTextbuf()
}
//Maybe a new line is too big for the whole new line? Then we have to split it
if (!br) && (len * list.font_w >= draw_w) {
//debugln("bigbr");
//debugval("draw_x", draw_x);
//debugval("draw_w", draw_w);
br = draw_w - draw_x / list.font_w;
//debugval("cut into 1", br * list.font_w);
br = draw_w - draw_x + left_gap - BODY_MARGIN / list.font_w;
if (br < 0) {
NewLine();
br = draw_w - draw_x / list.font_w;
//debugval("cut into 2", br * list.font_w);
br = draw_w - draw_x + left_gap - BODY_MARGIN / list.font_w;
}
}
@@ -117,7 +111,6 @@ void TWebBrowser::RenderTextbuf()
if (ESBYTE[lbp]) NewLine();
} else {
NewLine();
RenderLine(lbp);
}
}
RenderLine(lbp);
+13 -6
View File
@@ -445,9 +445,16 @@ void EventScrollUpAndDown(int _direction)
void EventToggleDebugMode()
{
int cy = WB1.list.first;
debug_mode ^= 1;
if (debug_mode) notify("'Debug mode ON'-I");
else notify("'Debug mode OFF'-I");
WB1.Reparse();
WB1.list.first = WB1.list.cur_y = cy;
WB1.DrawPage();
if (debug_mode) {
DrawStatusBar("Debug mode = ON");
} else {
DrawStatusBar("Debug mode = OFF");
}
}
void EventAllTabsClick(dword _n)
@@ -792,11 +799,11 @@ bool UrlExtIs(dword base, ext)
void DrawProgress()
{
dword pct;
dword pct = 10, fullw = omnibox_edit.width + 23; // full omnibox width incl. icon
if (!http.transfer) return;
if (http_get_type==PAGE) && (prbar.max) pct = prbar.value*30/prbar.max; else pct = 10;
if (http_get_type==IMG) pct = prbar.value * 70 / prbar.max + 30;
DrawBar(omnibox_edit.left-1, omnibox_edit.top+20, pct*omnibox_edit.width+23/100, 2, 0x72B7EB);
if (http_get_type==IMG) pct = prbar.value*70/prbar.max + 30;
if (http_get_type==PAGE) && (prbar.max) pct = prbar.value*30/prbar.max;
DrawBar(omnibox_edit.left-1, omnibox_edit.top+20, pct*fullw/100, 2, 0x72B7EB);
}
void EventShowPageMenu()
+121
View File
@@ -0,0 +1,121 @@
enum { TAG, OPTION_VALUE, TEXT, COMMENT, INLINE_COMMENT, CODE };
char* C_HL_keywords[] = {
"switch", "if", "while", "for", "break", "continue", "return", "else",
"union", "typedef", "static", "class", "case", "#include",
"volatile", "register", "sizeof", "typedef", "union", "goto", "const", "auto",
"#define", "#endif", "#error", "#ifdef", "#ifndef", "#undef", "#if", "#else",
"inline",
"int ", "dword ", "long ", "double ", "float ", "char ", "unsigned ", "signed ",
"void ", "bool ", "enum ", "byte ", "word ", "struct ", "NULL", "loop", "stdcall ",
":void ", ":int ", ":bool ", ":dword ", NULL
};
dword ShowCodeSource(dword _bufpointer, _bufsize)
{
dword new_buf, new_buf_start, i;
int mode = CODE;
char spstr[64];
dword keylen;
dword keyn;
dword keycolor;
new_buf = malloc(_bufsize*10);
new_buf_start = new_buf;
sprintf(new_buf,"<html><head><title>%s</title><body><pre>",#current_path);
new_buf += strlen(new_buf);
for (i=_bufpointer; i<_bufpointer+_bufsize; i++)
{
if ('<' == ESBYTE[i]) {
strcpy(new_buf, "&lt;");
new_buf+=4;
continue;
}
if ('>' == ESBYTE[i]) {
strcpy(new_buf, "&gt;");
new_buf+=4;
continue;
}
if (ESBYTE[i] >= '0') && (ESBYTE[i] <= '9') && (CODE == mode) {
strcpy(new_buf, "<font color=#CF00FF>?</font>");
ESBYTE[new_buf+20] = ESBYTE[i];
new_buf+=28;
if (ESBYTE[i+1] == 'x') {
strcpy(new_buf, "<font color=#CF00FF>x</font>");
new_buf+=28;
i++;
}
continue;
}
if (CODE == mode) && ('\"' == ESBYTE[i]) {
mode = TEXT;
strcpy(new_buf, "<font color=#080>\"");
new_buf+=18;
continue;
}
if (TEXT == mode) && ('\"' == ESBYTE[i]) {
mode = CODE;
strcpy(new_buf, "\"</font>");
new_buf+=8;
continue;
}
if (! strncmp(i, "//", 2) ) && (mode == CODE) {
mode = INLINE_COMMENT;
strcpy(new_buf, "<font color=#999>//");
new_buf+=19;
i++;
continue;
}
if (INLINE_COMMENT == mode) {
if (13 == ESBYTE[i]) {
mode = CODE;
strcpy(new_buf, "\13</font>");
new_buf+=8;
continue;
}
}
if (! strncmp(i, "/*", 2) ) {
mode = COMMENT;
strcpy(new_buf, "<font color=#999>/*");
new_buf+=19;
i++;
continue;
}
if (! strncmp(i, "*/", 2) ) {
mode = CODE;
strcpy(new_buf, "*/</font>");
new_buf+=9;
i++;
continue;
}
if (CODE == mode) for (keyn=0; C_HL_keywords[keyn]!=NULL; keyn++)
{
keylen = strlen(C_HL_keywords[keyn]);
if (! strncmp(i, C_HL_keywords[keyn], keylen) ) {
if (keyn<31) keycolor="#f00"; else keycolor="#00f";
sprintf(#spstr, "<font color=%s>%s</font>", keycolor, C_HL_keywords[keyn]);
strcpy(new_buf, #spstr);
new_buf += keylen + 24;
i += keylen-1;
goto _CONTINUE;
}
}
ESBYTE[new_buf] = ESBYTE[i];
new_buf++;
_CONTINUE:
}
ESBYTE[new_buf] = 0;
LoadInternalPage(new_buf_start, new_buf - new_buf_start);
free(new_buf_start);
}
+1 -1
View File
@@ -41,7 +41,7 @@
* +
' |
() .-.,="``"=. - o -
'=/_ \ |
'=/_ \ |
* | '=.<a href=WebView:test>&nbsp;</a> |
\ `=./`, '
. '=.__.=' `=' *
+5 -1
View File
@@ -32,4 +32,8 @@
<a href=//artcon.ru>artcon.ru</a> <a href=//nubo.ru>nubo.ru</a> <a href=//nostalgy.net.ru/>nostalgy.net.ru</a> <a href=//acmp.ru/index.asp?main=tasks>acmp.ru</a>
<a href=//opennet.ru>opennet</a> <a href=//linux.org.ru>LOR</a>
<a href=//samlib.ru/b>samlib.ru/b</a>
<a href=//os-menuet.narod.ru>os-menuet.narod.ru</a> <a href=//coolthemes.narod.ru/indexold.html>coolthemes.narod.ru</a>
<a href=//os-menuet.narod.ru>os-menuet.narod.ru</a> <a href=//coolthemes.narod.ru/indexold.html>coolthemes.narod.ru</a>
+1 -1
View File
@@ -58,7 +58,7 @@
char dl_shared[] = "DL";
#define URL_SPEED_TEST "http://speedtest.tele2.net/100MB.zip"
#define URL_SPEED_TEST "http://kolibrios.org/speedtest/100MB.zip"
enum {
BTN_EXIT=1,
+58 -38
View File
@@ -32,6 +32,7 @@ char proxy_address[256];
#include "settings.h"
char* active_status;
int save_path_set = false;
edit_box ed = {WIN_W-GAPX-GAPX,GAPX,20,0xffffff,0x94AECE,0xffffff,0xffffff,
0x10000000, sizeof(uEdit)-2, #uEdit, 0, ed_focus + ed_always_focus, 19, 19};
@@ -41,6 +42,8 @@ progress_bar pb = {0, GAPX, 52, WIN_W - GAPX - GAPX, 17, 0, NULL, NULL,
void main()
{
dword save_path_separator_pos;
dword path_pointer;
// dword shared_url; // only used by the disabled -mem branch (long URL via SHM)
load_dll(libini, #lib_init,1);
@@ -56,14 +59,21 @@ void main()
InitDownload();
if (param) {
path_pointer = #param;
//save path specified? Example: https://example.com/file|/sys/media/ac97snd
if (save_path_separator_pos = strchr(#param, '|')) {
save_path_set = true;
strcpy(#filepath, save_path_separator_pos+1);
ESBYTE[save_path_separator_pos] = '\0';
}
if (streqrp(#param, "-e ")) {
autoclose.checked = true;
param += 3;
path_pointer += 3;
}
if (streqrp(#param, "-eo ")) {
autoclose.checked = true;
open_file = true;
param += 4;
path_pointer += 4;
}
// Disabled long-URL-via-SHM ("DL") channel. memopen was never
@@ -73,12 +83,12 @@ void main()
// shared_url = memopen(#dl_shared, URL_SIZE+1, SHM_OPEN + SHM_WRITE);
// strcpy(#uEdit, shared_url);
// } else {
strcpy(#uEdit, #param);
// }
if (streq(#param, "-test")) {
strcpy(#uEdit, URL_SPEED_TEST);
} else {
strcpy(#uEdit, path_pointer);
}
// }
}
if (uEdit[0]) StartDownloading(); else {
edit_box_set_text stdcall (#ed, "http://");
@@ -172,7 +182,11 @@ void DrawWindow()
DrawBar(GAPX, WIN_H - 58, WIN_W - GAPX - GAPX, 1, sc.light);
DrawBar(GAPX, WIN_H - 58 + 1, WIN_W - GAPX - GAPX, 1, sc.dark);
WriteTextWithBg(GAPX, WIN_H - 48, 0xD0, sc.work_text, T_SAVE_TO, sc.work);
WriteTextWithBg(GAPX + 108, WIN_H - 48, 0xD0, sc.work_text, #save_dir, sc.light);
if (save_path_set) {
WriteTextWithBg(GAPX + 108, WIN_H - 48, 0xD0, sc.work_text, #filepath, sc.light);
} else {
WriteTextWithBg(GAPX + 108, WIN_H - 48, 0xD0, sc.work_text, #save_dir, sc.light);
}
edit_box_draw stdcall (#ed);
progressbar_draw stdcall(#pb);
autoclose.draw(GAPX, WIN_H - 24);
@@ -305,41 +319,47 @@ void SaveFile(int attempt)
char notify_message[4296];
char file_name[URL_SIZE+96];
//if save_path is not set then we have to combine it
if (!save_path_set) {
strcpy(#filepath, #save_dir);
chrcat(#filepath, '/'); ///need to check the last symbol
strcpy(#filepath, #save_dir);
chrcat(#filepath, '/'); ///need to check the last symbol
if (attempt > 9) {
notify("'Too many saving attempts' -E");
return;
}
if (attempt > 0) {
chrcat(#filepath, attempt+'0');
chrcat(#filepath, '_');
}
//Content-Disposition: attachment; filename="RealFootball_2018_Nokia_5800_EN_IGP_EU_TS_101.zip"
if (http.header_field("content-disposition", #file_name, sizeof(file_name))) {
if (EDX = strstr(#file_name,"filename=\"")) {
strcat(#filepath, EDX+10);
ESBYTE[strchr(#filepath,'\"')] = '\0';
if (attempt > 9) {
notify("'Too many saving attempts' -E");
return;
}
} else {
// Clean all slashes at the end
strcpy(#file_name, #uEdit);
while (file_name[strlen(#file_name)-1] == '/') {
file_name[strlen(#file_name)-1] = 0;
}
strcat(#filepath, #file_name+strrchr(#file_name, '/'));
}
for (i=0; i<strlen(#filepath); i++) if(filepath[i]==':')||(filepath[i]=='?')filepath[i]='-';
while (file_exists(#filepath)) {
SaveFile(attempt+1);
return;
}
if (attempt > 0) {
chrcat(#filepath, attempt+'0');
chrcat(#filepath, '_');
}
//Content-Disposition: attachment; filename="RealFootball_2018_Nokia_5800_EN_IGP_EU_TS_101.zip"
if (http.header_field("content-disposition", #file_name, sizeof(file_name))) {
if (EDX = strstr(#file_name,"filename=\"")) {
strcat(#filepath, EDX+10);
ESBYTE[strchr(#filepath,'\"')] = '\0';
}
} else {
// Clean all slashes at the end
strcpy(#file_name, #uEdit);
while (file_name[strlen(#file_name)-1] == '/') {
file_name[strlen(#file_name)-1] = 0;
}
strcat(#filepath, #file_name+strrchr(#file_name, '/'));
}
for (i=0; i<strlen(#filepath); i++) if(filepath[i]==':')||(filepath[i]=='?')filepath[i]='-';
}
// When an explicit save path is given, overwrite it instead of
// auto-renaming - otherwise the fixed path always exists and recurses forever.
if (!save_path_set) {
while (file_exists(#filepath)) {
SaveFile(attempt+1);
return;
}
}
if (CreateFile(http.content_received, http.content_pointer, #filepath)==0) {
miniprintf(#notify_message, T_FILE_SAVED_AS, #filepath);
+1 -1
View File
@@ -260,7 +260,7 @@ inline fastcall void GetCurDir( ECX, EDX)
previous but here virtual folders like
'/' and '/tmp' are not recognised as FOLDERS
by GetFileInfo() => BDVK.isfolder attribute :( */
bool real_dir_exists(dword fpath)
:bool real_dir_exists(dword fpath)
{
BDVK fpath_atr;
if (GetFileInfo(fpath, #fpath_atr) != 0) return false;
+14 -10
View File
@@ -905,16 +905,20 @@ inline signed csshexdec(dword text)
:dword miniprintf(dword dst, format, insert_line)
{
dword in_pos = strchr(format, '%');
EBX = ESBYTE[EAX+1];
if (EBX == 's') {
strncpy(dst, format, in_pos - format);
strcat(dst, insert_line);
strcat(dst, in_pos+2);
}
if (EBX == 'd') || (EBX == 'i') {
strncpy(dst, format, in_pos - format);
strcat(dst, itoa(insert_line));
strcat(dst, in_pos+2);
if (!in_pos) || (!insert_line) {
strcpy(dst, format);
} else {
EBX = ESBYTE[EAX+1];
if (EBX == 's') {
strncpy(dst, format, in_pos - format);
strcat(dst, insert_line);
strcat(dst, in_pos+2);
}
if (EBX == 'd') || (EBX == 'i') {
strncpy(dst, format, in_pos - format);
strcat(dst, itoa(insert_line));
strcat(dst, in_pos+2);
}
}
return dst;
}
+310
View File
@@ -0,0 +1,310 @@
/* # KolibriOS Image Unpacker #
FAT12 floppy image unpacker.
Usage: unimg path/to/img [output/folder]
If output folder is skipped, the image will be unpacked at /TMP0/1/[file-name.ext]
Author: Magomed Kostoev (Boppan, mkostoevr): author of initial version in C
Kyryl Lipatov (Leency): rewrite to C--, use any image type. */
#define MEMSIZE 1024*30
#define ENTRY_POINT #main
#include "../lib/fs.h"
// NB: this file is stored in CP866 (for the Russian strings below).
// Edit it with a CP866-aware editor, not UTF-8.
#ifdef LANG_RUS
?define MSG_USAGE "'unimg\nРаспаковщик дискет FAT12.\nИспользование: unimg /путь/к/образу [\"/папка/вывода\"]' -tI"
?define MSG_READ "'unimg\nОшибка чтения файла\n%s' -tE"
?define MSG_FORMAT "'unimg\nОбраз не FAT12.\n%s' -tE"
?define MSG_MKDIR "'unimg\nОшибка создания папки\n%s' -tE"
?define MSG_DONE "'unimg\nРаспаковано в:\n%s' -tO"
?define MSG_NOMEM "'unimg\nНедостаточно памяти' -tE"
?define MSG_OOB "'unimg\nКластера FAT вне границ' -tE"
?define INFO_NAME "\nВнутреннее имя "
?define INFO_BPS "\nБайт на сектор "
?define INFO_SPC "\nСекторов в кластере "
?define INFO_RSC "\nРезервных секторов "
?define INFO_NFAT "\nКоличество FAT "
?define INFO_MRE "\nЗаписей в корне "
?define INFO_BPC "\nБайт в кластере "
?define INFO_SPF "\nСекторов на FAT "
?define INFO_FATOFF "\nПервая FAT "
?define INFO_ROOTOFF "\nКорневой каталог "
?define INFO_DATAOFF "\nОбласть данных "
#else
?define MSG_USAGE "'unimg\nFAT12 floppy image unpacker.\nUsage: unimg /path/to/img [\"/output/dir\"]' -tI"
?define MSG_READ "'unimg\nFile read error\n%s' -tE"
?define MSG_FORMAT "'unimg\nNot a FAT12 image.\n%s' -tE"
?define MSG_MKDIR "'unimg\nCannot create output folder\n%s' -tE"
?define MSG_DONE "'unimg\nUnpacked to\n%s' -tO"
?define MSG_NOMEM "'unimg\nOut of memory' -tE"
?define MSG_OOB "'unimg\nFAT cluster out of bounds' -tE"
?define INFO_NAME "\nInternal name "
?define INFO_BPS "\nBytes per sector "
?define INFO_SPC "\nSectors per cluster "
?define INFO_RSC "\nReserved sectors "
?define INFO_NFAT "\nNumber of FATs "
?define INFO_MRE "\nMax root entries "
?define INFO_BPC "\nBytes per cluster "
?define INFO_SPF "\nSectors per FAT "
?define INFO_FATOFF "\nFirst FAT "
?define INFO_ROOTOFF "\nRoot directory "
?define INFO_DATAOFF "\nData region "
#endif
dword img_ptr;
dword img_sz;
int bps;
int spc;
int rsc;
int nfat;
int mre;
int spf;
int bpc;
int fat_off;
int root_off;
int data_off;
char cur_path[4096];
int cur_path_len;
inline int fat_u8(int offset) { return DSBYTE[img_ptr + offset] & 0xFF; }
inline int fat_u16(int offset) { return DSWORD[img_ptr + offset] & 0xFFFF; }
inline dword fat_u32(int offset) { return ESDWORD[img_ptr + offset]; }
void fat12__open()
{
bps = fat_u16(11);
spc = fat_u8(13);
rsc = fat_u16(14);
nfat = fat_u8(16);
mre = fat_u16(17);
spf = fat_u16(22);
bpc = bps * spc;
fat_off = rsc * bps;
root_off = nfat * spf * bps + fat_off;
data_off = mre * 32 + root_off;
}
dword GetImageInfo(dword buf)
{
//strcpy(buf, INFO_NAME); strncpy(buf+21, img_ptr+3, 8);
strcat(buf, INFO_BPS); strcat(buf, itoa(bps));
strcat(buf, INFO_SPC); strcat(buf, itoa(spc));
strcat(buf, INFO_RSC); strcat(buf, itoa(rsc));
strcat(buf, INFO_NFAT); strcat(buf, itoa(nfat));
strcat(buf, INFO_MRE); strcat(buf, itoa(mre));
strcat(buf, INFO_BPC); strcat(buf, itoa(bpc));
strcat(buf, INFO_SPF); strcat(buf, itoa(spf));
strcat(buf, INFO_FATOFF); strcat(buf, itoa(fat_off));
strcat(buf, INFO_ROOTOFF); strcat(buf, itoa(root_off));
strcat(buf, INFO_DATAOFF); strcat(buf, itoa(data_off));
}
int cluster_to_offset(int c)
{
return c - 2 * bpc + data_off;
}
int next_cluster(int c)
{
int v;
v = fat_u16(c / 2 + fat_off + c);
if (c & 1) return v >> 4;
return v & 0xFFF;
}
void extract_file(dword buf, int size, int cluster)
{
int written, n, src;
written = 0;
while (cluster >= 2) && (cluster < 0xFF7) {
src = cluster_to_offset(cluster);
n = bpc;
// clamp to remaining size
if (written + n > size) n = size - written;
if (n <= 0) break;
// Stop on a corrupt FAT chain pointing outside the image
if (src < 0) || (src + n > img_sz) break;
memmov(buf + written, img_ptr + src, n);
written += n;
cluster = next_cluster(cluster);
}
}
void make_parent_dirs(dword initial_dir)
{
char path[4096];
int i;
strncpy(#path, initial_dir, strlen(initial_dir) + 1);
//debugln(#path);
for (i = 1; path[i]; i++) {
if (path[i] == '/') {
path[i] = '\0';
CreateDir(#path);
path[i] = '/';
}
}
}
int entry_short_name(int off, dword out)
{
int attr, i, n, b;
b = fat_u8(off);
if (!b) return -1;
if (b == 0xE5) return 0;
attr = fat_u8(off + 11);
if (attr & 0x0F == 0x0F) return 0;
if (attr & 0x08) return 0;
n = 0;
for (i = 0; i < 8; i++) {
b = fat_u8(off + i);
if (b == ' ') break;
ESBYTE[out + n] = b;
n++;
}
b = fat_u8(off + 8);
if (b != ' ') {
ESBYTE[out + n] = '.';
n++;
for (i = 8; i < 11; i++) {
b = fat_u8(off + i);
if (b == ' ') break;
ESBYTE[out + n] = b;
n++;
}
}
ESBYTE[out + n] = '\0';
return n;
}
int handle_entry(int off)
{
char name[13];
int nlen, attr, cluster, size, saved_len;
dword buf;
if (off < 0) || (off + 32 > img_sz) {
return -1;
}
nlen = entry_short_name(off, #name);
if (nlen < 0) return -1;
if (nlen == 0) return 0;
if (name[0] == '.') return 0;
attr = fat_u8(off + 11);
cluster = fat_u16(off + 26);
saved_len = cur_path_len;
cur_path[cur_path_len] = '/';
memmov(#cur_path + cur_path_len + 1, #name, nlen + 1);
cur_path_len = cur_path_len + 1 + nlen;
if (attr & 0x10) {
CreateDir(#cur_path);
handle_folder(cluster);
} else {
size = fat_u32(off + 28);
if (size > 0) {
buf = malloc(size);
if (!buf) {
notify(MSG_NOMEM);
} else {
extract_file(buf, size, cluster);
CreateFile(size, buf, #cur_path);
free(buf);
}
} else {
CreateFile(0, img_ptr, #cur_path);
}
}
cur_path_len = saved_len;
cur_path[cur_path_len] = '\0';
return 0;
}
void handle_folder(int cluster)
{
int off, entries, i;
while (cluster >= 2) && (cluster < 0xFF7) {
off = cluster_to_offset(cluster);
// Check that offset don't go negative
// and we don't read over img size (img_sz)
if (off < 0) || (off + bpc > img_sz) {
notify(MSG_OOB);
return;
}
entries = bpc / 32;
for (i = 0; i < entries; i++) {
if (handle_entry(i * 32 + off) < 0) return;
}
cluster = next_cluster(cluster);
}
}
void NotifyAndExit(dword message, opt)
{
miniprintf(#param, message, opt);
notify(#param);
ExitProcess();
}
void main()
{
char img_file[4096];
char img_info[512];
int i;
mem_init();
if (!param[0]) {
NotifyAndExit(MSG_USAGE, NULL);
}
if (i = strchr(#param, '"')) {
ESBYTE[i-1] = '\0';
strcpy(#cur_path, i+1);
i = strchr(#cur_path, '"');
if (i) ESBYTE[i] = '\0';
}
strcpy(#img_file, #param);
if (!cur_path[0]) {
memmov(#cur_path, "/tmp0/1", 8);
strcat(#cur_path, #img_file + strrchr(#img_file, '/') - 1);
}
cur_path_len = strlen(#cur_path);
read_file(#img_file, #img_ptr, #img_sz);
if (!img_ptr) || (!img_sz) {
NotifyAndExit(MSG_READ, #img_file);
}
fat12__open();
if (root_off > img_sz) || (data_off > img_sz) {
GetImageInfo(#img_info);
NotifyAndExit(MSG_FORMAT, #img_info);
}
make_parent_dirs(#cur_path);
if (CreateDir(#cur_path)) {
NotifyAndExit(MSG_MKDIR, #cur_path);
}
for (i = 0; i < mre; i++) {
if (handle_entry(i * 32 + root_off) < 0) break;
}
NotifyAndExit(MSG_DONE, #cur_path);
}
+11 -10
View File
@@ -1,4 +1,4 @@
// Mouse Configuration Utility ver 1.7
// Mouse Configuration Utility ver 1.71
#define MEMSIZE 4096*11
@@ -64,11 +64,13 @@ void main() {
{
case evMouse:
mouse.get();
IF (mouse_frame.hovered()) DrawMouseImage(mouse.lkm,mouse.pkm,mouse.mkm,mouse.vert);
IF (mouse.click) || (mouse.up) DrawMouseImage(0,0,0,0);
IF (mouse_frame.hovered()) {
DrawMouseImage(mouse.key&MOUSE_LEFT,mouse.key&MOUSE_RIGHT,mouse.key&MOUSE_MIDDLE,mouse.vert);
}
if (mouse.up) DrawMouseImage(0,0,0,0);
break;
CASE evButton:
case evButton:
id = @GetButtonID();
IF (1 == id) ExitApp();
else IF (pointer_speed.click(id)) ApplyCfg();
@@ -119,21 +121,20 @@ void main() {
#define white 0xffffff
#define dgrey 0x2d353d
:struct IMG_PAL{ dword back, shad1, contour, left, right, middle, mwhite; }
struct IMG_PAL{ dword back, shad1, contour, left, right, middle, mwhite; }
pal = { 0xF0F2F3,0xABB0B2, dgrey, white, white, dgrey, white };
void DrawMouseImage(dword l,r,m,v) {
#define IMG_W 59
#define IMG_H 100
IF (l) pal.left = red;
IF (l) pal.left = red; else pal.left = white;
IF (r) pal.right = red; else pal.right = white;
IF (m) pal.middle = red;
IF (r) pal.right = red;
IF (v) pal.middle = yellow;
ELSE IF (v) pal.middle = yellow;
ELSE pal.middle = dgrey;
PutPaletteImage(#panels_img_data,IMG_W,IMG_H,18+30,18+16,8,#pal);
pal.left = pal.right = white;
pal.middle = dgrey;
IF (v) {
pause(10);
DrawMouseImage(l,r,m,0);
+13 -2
View File
@@ -29,7 +29,7 @@
char default_dir[] = "/sys";
od_filter filter2 = { 15, "MP3\0WAV\0XM\0\0" };
#define ABOUT_MESSAGE " v2.94 Final
#define ABOUT_MESSAGE " v2.95 Final
A tiny music folder player.
Supports MP3, WAV, XM audio file formats.
@@ -415,6 +415,7 @@ void EventStopPlaying()
void EventStartPlaying()
{
word i;
dword dl_run_id;
char item_path[4096];
char notify_message[512];
EventStopPlaying();
@@ -433,7 +434,17 @@ void EventStartPlaying()
DrawPlayList();
DrawTopPanel();
//start_playing_time =
player_run_id = RunProgram("/sys/media/ac97snd", #item_path);
player_run_id = RunProgram("/sys/media/ac97snd", #item_path);
if (player_run_id < 0) {
dl_run_id = RunProgram("/sys/network/dl", "-e http://builds.kolibrios.org/en_US/data/programs/media/ac97snd/ac97snd.bin|/sys/media/ac97snd");
// wait for the downloader to finish (it autocloses on completion), up to ~30s
for (i=0; i<50; i++) {
pause(10);
if (!GetProcessSlot(dl_run_id)) break;
}
player_run_id = RunProgram("/sys/media/ac97snd", #item_path);
if (player_run_id < 0) notify("'AC97SND backend not found and its download failed :('-E");
}
//player_run_id = RunProgram("/kolibrios/media/minimp3", #item_path);
sprintf(#notify_message,"'Now playing:\n%s' -St",#current_filename);
if (!repeat) && (window_mode==WINDOW_MODE_SMALL)