apps/cmm: take the c-- programs and the compiler config from their repositories (#585)
Reviewed-on: #585 Reviewed-by: Kiril Lipatov <lipatov.kiril@gmail.com> Reviewed-by: bad_Dr3dd0x <1702+bad_dr3dd0x@noreply.localhost>
This commit was merged in pull request #585.
This commit is contained in:
@@ -62,7 +62,7 @@ jobs:
|
||||
make -f Makefile.lin32
|
||||
chmod +x c--
|
||||
mv c-- /home/autobuild/tools/win32/bin/c--
|
||||
cp ${{ gitea.workspace }}/programs/cmm/c--/c--.ini /home/autobuild/tools/win32/bin/c--.ini
|
||||
cp ${{ gitea.workspace }}/programs/develop/cmm/c--.ini /home/autobuild/tools/win32/bin/c--.ini
|
||||
make -f Makefile.lin32 clean
|
||||
|
||||
- name: Install TCC
|
||||
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
make -f Makefile.lin32
|
||||
chmod +x c--
|
||||
mv c-- /home/autobuild/tools/win32/bin/c--
|
||||
cp ${{ gitea.workspace }}/programs/cmm/c--/c--.ini /home/autobuild/tools/win32/bin/c--.ini
|
||||
cp ${{ gitea.workspace }}/programs/develop/cmm/c--.ini /home/autobuild/tools/win32/bin/c--.ini
|
||||
make -f Makefile.lin32 clean
|
||||
|
||||
- name: Install TCC
|
||||
|
||||
@@ -24,6 +24,8 @@ jobs:
|
||||
path: programs/develop/cmm
|
||||
- name: oberon07
|
||||
path: programs/develop/oberon07
|
||||
- name: cmm_apps
|
||||
path: programs/cmm
|
||||
- name: kterm
|
||||
path: programs/other/kterm
|
||||
|
||||
@@ -68,7 +70,7 @@ jobs:
|
||||
git config user.name "kolibri-bot"
|
||||
git config user.email "bot@kolibrios.org"
|
||||
git checkout -B "$BRANCH"
|
||||
git commit -m "$NAME: bump submodule to $WANT" -- "$PATH_"
|
||||
git commit -m "chore/submodules: bump $NAME to $WANT" -- "$PATH_"
|
||||
git push -f origin "$BRANCH"
|
||||
|
||||
# Open a PR via the Gitea API.
|
||||
@@ -77,7 +79,7 @@ jobs:
|
||||
http=$(curl -sS -o /tmp/pr.json -w '%{http_code}' -X POST \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"head\":\"${BRANCH}\",\"base\":\"main\",\"title\":\"${NAME}: bump submodule to upstream\"}" \
|
||||
-d "{\"head\":\"${BRANCH}\",\"base\":\"main\",\"title\":\"chore/submodules: bump ${NAME} to upstream\"}" \
|
||||
"${API}/repos/${REPO}/pulls")
|
||||
echo "PR API HTTP status: $http"
|
||||
cat /tmp/pr.json; echo
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
path = programs/develop/oberon07
|
||||
url = https://github.com/AntKrotov/oberon-07-compiler.git
|
||||
branch = master
|
||||
[submodule "programs/cmm"]
|
||||
path = programs/cmm
|
||||
url = https://git.kolibrios.org/KolibriOS/cmm_apps.git
|
||||
branch = main
|
||||
[submodule "programs/other/kterm"]
|
||||
path = programs/other/kterm
|
||||
url = https://git.kolibrios.org/b00bl1k/kterm.git
|
||||
|
||||
+2
-2
@@ -170,8 +170,6 @@ extra_files = {
|
||||
{"kolibrios/demos/life2", "common/demos/life2"},
|
||||
{"kolibrios/demos/relay.lif", "common/demos/relay.lif"},
|
||||
{"kolibrios/demos/rpento.lif", "common/demos/rpento.lif"},
|
||||
{"kolibrios/develop/c--/c--.ini", SRC_PROGS .. "/cmm/c--/c--.ini"},
|
||||
{"kolibrios/develop/c--/manual_c--.htm", SRC_PROGS .. "/cmm/c--/manual_c--.htm"},
|
||||
{"kolibrios/develop/fpc/", "common/develop/fpc/*"},
|
||||
{"kolibrios/develop/fpc/examples/", "../programs/develop/fp/examples/src/*"},
|
||||
{"kolibrios/develop/oberon07/compiler.kex", SRC_PROGS .. "/develop/oberon07/Compiler.kex"},
|
||||
@@ -812,6 +810,8 @@ tup.append_table(extra_files, {
|
||||
{"kolibrios/utils/minizip/minizip", VAR_PROGS .. "/fs/minizip/minizip"},
|
||||
{"kolibrios/utils/minizip/miniunz", VAR_PROGS .. "/fs/minizip/miniunz"},
|
||||
{"kolibrios/develop/c--/c--", VAR_PROGS .. "/develop/cmm/cmm"},
|
||||
{"kolibrios/develop/c--/c--.ini", SRC_PROGS .. "/develop/cmm/c--.ini"},
|
||||
{"kolibrios/develop/c--/manual_c--.htm", SRC_PROGS .. "/develop/cmm/manual_c--.htm"},
|
||||
{"kolibrios/develop/tcc/tcc", VAR_PROGS .. "/develop/ktcc/source/tcc"},
|
||||
{"kolibrios/develop/sqlite3/sqlite3", VAR_CONTRIB .. "/sdk/sources/sqlite3/shell/sqlite3"},
|
||||
{"kolibrios/develop/utils/objconv", VAR_PROGS .. "/develop/objconv/objconv"},
|
||||
|
||||
Submodule
+1
Submodule programs/cmm added at 4678e1605d
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("app_plus.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "app_plus.com")
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
struct sysdir
|
||||
{
|
||||
char name[64];
|
||||
char path[64];
|
||||
} sysdir;
|
||||
|
||||
|
||||
:int SetAdditionalSystemDirectory(dword tName, tPath)
|
||||
{
|
||||
int i;
|
||||
strcpy(#sysdir.name, tName);
|
||||
strcpy(#sysdir.path, tPath);
|
||||
$mov eax, 30
|
||||
$mov ebx, 3
|
||||
ECX = #sysdir;
|
||||
$int 0x40
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
#define MEMSIZE 1024*60
|
||||
|
||||
#include "..\lib\gui.h"
|
||||
#include "..\lib\obj\proc_lib.h"
|
||||
#include "..\lib\patterns\simple_open_dialog.h"
|
||||
#include "..\lib\patterns\restart_process.h"
|
||||
#include "added_sysdir.c"
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// DATA //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
#define WINW 570
|
||||
#define WINH 300
|
||||
#define CONX 28 //content X pos
|
||||
#define CONY 25 //content Y pos
|
||||
|
||||
char default_dir[] = "/sys";
|
||||
od_filter filter2;
|
||||
|
||||
#define BTN_MANUAL_SEARCH 10
|
||||
#define BTN_OPEN_ANYWAY 11
|
||||
|
||||
#define APP_PLUS_INI_PATH "/sys/settings/app_plus.ini"
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// TRANSLATIONS //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
#ifdef LANG_RUS
|
||||
?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!"
|
||||
?define CONTENT_HEADER_TEXT "KolibriOS is running in floppy mode"
|
||||
?define DESCRIPTION_TEXT "A lot of apps aren't available.
|
||||
|
||||
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
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// CODE //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void main()
|
||||
{
|
||||
if (param) {
|
||||
SetAdditionalSystemDirectory("kolibrios", #param+1);
|
||||
ExitProcess();
|
||||
}
|
||||
|
||||
WaitAutosearch();
|
||||
CheckKosMounted();
|
||||
|
||||
o_dialog.type = 2;
|
||||
#define NO_DLL_INIT
|
||||
load_dll(Proc_lib, #OpenDialog_init,0);
|
||||
OpenDialog_init stdcall (#o_dialog);
|
||||
active_button_id = BTN_MANUAL_SEARCH;
|
||||
|
||||
loop() switch(@WaitEvent())
|
||||
{
|
||||
case evButton:
|
||||
EventButton(GetButtonID());
|
||||
break;
|
||||
case evKey:
|
||||
@GetKeyScancode();
|
||||
if (AL == SCAN_CODE_ENTER) {
|
||||
EventButton(active_button_id);
|
||||
} else if (AL == SCAN_CODE_TAB) {
|
||||
active_button_id = active_button_id-10^1 + 10;
|
||||
DrawButtons();
|
||||
}
|
||||
break;
|
||||
|
||||
case evReDraw:
|
||||
draw_window();
|
||||
}
|
||||
}
|
||||
|
||||
void draw_window()
|
||||
{
|
||||
sc.get();
|
||||
DefineAndDrawWindow(screen.w-WINW/2, 100, WINW, WINH+skin_h, 0x34, sc.work, WINDOW_TITLE_TEXT,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-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 (file_exists(APP_PLUS_INI_PATH)) EventOpenApp();
|
||||
ExitProcess();
|
||||
}
|
||||
}
|
||||
|
||||
void WaitAutosearch()
|
||||
{
|
||||
while (CheckProcessExists("SEARCHAP")) pause(2);
|
||||
}
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// EVENTS //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void EventManualSearch()
|
||||
{
|
||||
OpenDialog_start stdcall (#o_dialog);
|
||||
if (o_dialog.status) SetAdditionalSystemDirectory("kolibrios", #openfile_path+1);
|
||||
pause(3);
|
||||
CheckKosMounted();
|
||||
}
|
||||
|
||||
void EventOpenApp()
|
||||
{
|
||||
if (RunProgram("/sys/syspanel", APP_PLUS_INI_PATH) < 0) {
|
||||
notify("'App+ cannot start because\n/sys/syspanel does not exist' -E");
|
||||
}
|
||||
}
|
||||
|
||||
void EventButton(dword id)
|
||||
{
|
||||
if (id==CLOSE_BTN) ExitProcess();
|
||||
else if (id==BTN_MANUAL_SEARCH) EventManualSearch();
|
||||
else if (id==BTN_OPEN_ANYWAY) {
|
||||
EventOpenApp();
|
||||
ExitProcess();
|
||||
}
|
||||
}
|
||||
|
||||
stop:
|
||||
@@ -1,6 +0,0 @@
|
||||
@c-- /D=LANG_ENG app_plus.c
|
||||
@del *.
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
@pause
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
@c-- /D=LANG_RUS app_plus.c
|
||||
@del *.
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
@pause
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("appearance.c", "c-- /D=AUTOBUILD /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "appearance.com")
|
||||
@@ -1,472 +0,0 @@
|
||||
//11.03.12 - start!
|
||||
|
||||
#define MEMSIZE 1024*70
|
||||
#include "../lib/mem.h"
|
||||
#include "../lib/strings.h"
|
||||
#include "../lib/io.h"
|
||||
#include "../lib/list_box.h"
|
||||
#include "../lib/gui.h"
|
||||
|
||||
#include "../lib/obj/box_lib.h"
|
||||
#include "../lib/obj/proc_lib.h"
|
||||
#include "../lib/obj/libini.h"
|
||||
|
||||
#include "../lib/patterns/select_list.h"
|
||||
#include "../lib/patterns/simple_open_dialog.h"
|
||||
#include "../lib/patterns/restart_process.h"
|
||||
|
||||
dword fmas;
|
||||
|
||||
#include "ui_elements_preview.h"
|
||||
#include "const.h"
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// DATA //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
int active_skin=-1, active_wallpaper=-1, active_screensaver=-1;
|
||||
|
||||
checkbox optionbox_stretch = { T_CHECKBOX_STRETCH, false };
|
||||
checkbox optionbox_tiled = { T_CHECKBOX_TILED, false };
|
||||
checkbox optionbox_auto = { T_CHECKBOX_AUTO, true };
|
||||
|
||||
char ss_available[200];
|
||||
|
||||
collection list;
|
||||
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// CODE //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void main()
|
||||
{
|
||||
int id, i;
|
||||
load_dll(boxlib, #box_lib_init,0);
|
||||
load_dll(libini, #lib_init,1);
|
||||
load_dll(Proc_lib, #OpenDialog_init,0);
|
||||
OpenDialog_init stdcall (#o_dialog);
|
||||
|
||||
GetIniSettings();
|
||||
|
||||
tabs.add(#t_skins, #EventTabSkinsClick);
|
||||
tabs.add(#t_wallpapers, #EventTabWallpappersClick);
|
||||
tabs.add(#t_screensaver, #EventTabScreensaverClick);
|
||||
tabs.draw_active_tab();
|
||||
|
||||
SetEventMask(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER);
|
||||
loop() switch(WaitEvent())
|
||||
{
|
||||
case evMouse:
|
||||
SelectList_ProcessMouse();
|
||||
if (tabs.active_tab == TAB_SCREENSAVERS) {
|
||||
scrollbar_h_mouse stdcall (#ss_timeout);
|
||||
if (ss_timeout.redraw) {
|
||||
draw_timeout();
|
||||
ss_timeout.redraw = false; //reset flag
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case evButton:
|
||||
id=GetButtonID();
|
||||
if (id==1) EventExit();
|
||||
tabs.click(id);
|
||||
if (tabs.active_tab == TAB_SKINS) {
|
||||
checkbox1.click(id);
|
||||
spinbox1.click(id);
|
||||
}
|
||||
if (tabs.active_tab == TAB_WALLPAPERS) {
|
||||
if (id==BTN_SELECT_WALLP_FOLDER) EventSelectWallpFolder();
|
||||
if (optionbox_stretch.click(id)) EventSetWallpMode(1,0,0);
|
||||
if (optionbox_tiled.click(id)) EventSetWallpMode(0,1,0);
|
||||
if (optionbox_auto.click(id)) EventSetWallpMode(0,0,1);
|
||||
}
|
||||
if (tabs.active_tab == TAB_SCREENSAVERS) {
|
||||
if (id==BTN_TEST_SCREENSAVER) EventOpenFile();
|
||||
if (id==BTN_SET_SCREENSAVER) EventSetSs();
|
||||
}
|
||||
break;
|
||||
|
||||
case evKey:
|
||||
GetKeys();
|
||||
if (select_list.ProcessKey(key_scancode)) { EventApply(); break; }
|
||||
if (key_scancode==SCAN_CODE_ENTER) { EventOpenFile(); break; }
|
||||
if (key_scancode==SCAN_CODE_DEL) { EventDeleteFile(); break; }
|
||||
if (key_scancode==SCAN_CODE_TAB) {
|
||||
id = tabs.active_tab+1;
|
||||
if(id==3)id=0;
|
||||
tabs.click(id + tabs.base_id);
|
||||
break;
|
||||
}
|
||||
for (i=select_list.cur_y+1; i<select_list.count; i++)
|
||||
{
|
||||
id = list.get(i) + strrchr(list.get(i), '/');
|
||||
if (ESBYTE[id]==key_ascii) || (ESBYTE[id]==key_ascii-32)
|
||||
{
|
||||
select_list.cur_y = i - 1;
|
||||
select_list.KeyDown();
|
||||
EventApply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case evReDraw:
|
||||
draw_window();
|
||||
}
|
||||
}
|
||||
|
||||
void draw_window()
|
||||
{
|
||||
sc.get();
|
||||
DefineAndDrawWindow(screen.w-WIN_W-9/2,80,WIN_W+9,WIN_H+4+skin_h,0x74,sc.work,WINDOW_HEADER,0);
|
||||
|
||||
DrawBar(0, 0, WIN_W, PANEL_H-2, sc.work); //top
|
||||
DrawBar(0, PANEL_H-2, LP-2, WIN_H-PANEL_H-LP+4, EDX); //left
|
||||
DrawBar(LIST_W+LP+20, PANEL_H-2, WIN_W-LIST_W-26, WIN_H-PANEL_H-LP+4, EDX); //right
|
||||
DrawBar(0, WIN_H-LP+2, WIN_W, LP-2, EDX); //bottom
|
||||
|
||||
tabs.draw();
|
||||
draw_icon_16w(tabs.x + TAB_P, LP+5, 17);
|
||||
draw_icon_16w(sizeof(t_skins)-1*8 + TAB_P + TAB_P + tabs.x, LP+5, 6);
|
||||
draw_icon_16w(sizeof(t_wallpapers)+sizeof(t_skins)-2*8 + TAB_P + TAB_P + TAB_P + tabs.x, LP+5, 61);
|
||||
|
||||
if (tabs.active_tab == TAB_SKINS)
|
||||
{
|
||||
DrawFrame(RIGHTx, PANEL_H+5, RIGHTw, RIGHTh, T_UI_PREVIEW);
|
||||
DrawUiElementsPreview(RIGHTx+20, PANEL_H+5, RIGHTh);
|
||||
}
|
||||
if (tabs.active_tab == TAB_WALLPAPERS)
|
||||
{
|
||||
DrawFrame(RIGHTx, PANEL_H+5, 180, 105, T_PICTURE_MODE);
|
||||
optionbox_stretch.draw(RIGHTx+14, PANEL_H+25);
|
||||
optionbox_tiled.draw(RIGHTx+14, PANEL_H+52);
|
||||
optionbox_auto.draw(RIGHTx+14, PANEL_H+79);
|
||||
DrawStandartCaptButton(RIGHTx, PANEL_H+130, BTN_SELECT_WALLP_FOLDER, T_SELECT_FOLDER);
|
||||
}
|
||||
if (tabs.active_tab == TAB_SCREENSAVERS)
|
||||
{
|
||||
draw_timeout();
|
||||
ss_timeout.line_col = sc.line;
|
||||
ss_timeout.frnt_col = sc.work;
|
||||
scrollbar_h_draw stdcall (#ss_timeout);
|
||||
DrawRectangle(RIGHTx, RIGHTy+25, RIGHTw-20, 15, sc.line);
|
||||
ESI = DrawStandartCaptButton(RIGHTx, PANEL_H + 65, BTN_TEST_SCREENSAVER, T_SS_PREVIEW);
|
||||
DrawStandartCaptButton(RIGHTx+ESI, PANEL_H + 65, BTN_SET_SCREENSAVER, T_SS_SET);
|
||||
}
|
||||
|
||||
$push select_list.cur_y
|
||||
SelectList_Init(
|
||||
LP,
|
||||
PANEL_H,
|
||||
LIST_W,
|
||||
WIN_H - LP - PANEL_H
|
||||
);
|
||||
$pop select_list.cur_y
|
||||
|
||||
SelectList_Draw();
|
||||
SelectList_DrawBorder();
|
||||
}
|
||||
|
||||
void draw_timeout()
|
||||
{
|
||||
miniprintf(#param, T_SS_TIMEOUT, ss_timeout.position+1);
|
||||
WriteTextWithBg(RIGHTx, PANEL_H, 0xD0, sc.work_text, #param, sc.work);
|
||||
}
|
||||
|
||||
void add_filesnames_into_the_list()
|
||||
{
|
||||
int j;
|
||||
for (j=0; j<select_list.count; j++) {
|
||||
miniprintf(#param,"%s/",#folder_path);
|
||||
strcat(#param, io.dir.position(ESDWORD[j*4+fmas]));
|
||||
list.add(#param);
|
||||
}
|
||||
}
|
||||
|
||||
void Open_Dir()
|
||||
{
|
||||
int j;
|
||||
dword ext;
|
||||
select_list.ClearList();
|
||||
|
||||
if (io.dir.buffer) free(io.dir.buffer);
|
||||
io.dir.load(#folder_path,DIR_ONLYREAL);
|
||||
|
||||
if (fmas) free(fmas);
|
||||
fmas = malloc(io.dir.count * 4);
|
||||
|
||||
for (j=0; j<io.dir.count; j++)
|
||||
{
|
||||
strncpy(#param, io.dir.position(j), PATHLEN);
|
||||
strlwr(#param);
|
||||
ext = #param + strrchr(#param,'.');
|
||||
if (tabs.active_tab==TAB_SKINS) {
|
||||
if (!streq(ext,"skn")) continue;
|
||||
}
|
||||
if (tabs.active_tab==TAB_WALLPAPERS) {
|
||||
if (!streq(ext,"png")) && (!streq(ext,"jpg"))
|
||||
&& (!streq(ext,"jpeg")) && (!streq(ext,"bmp"))
|
||||
&& (!streq(ext,"gif")) continue;
|
||||
}
|
||||
ESDWORD[select_list.count*4 + fmas] = j;
|
||||
select_list.count++;
|
||||
}
|
||||
sort_by_name(0, select_list.count-1);
|
||||
|
||||
list.drop();
|
||||
//save current item for tab change
|
||||
//add default item
|
||||
if(tabs.active_tab == TAB_SKINS)
|
||||
{
|
||||
select_list.count++;
|
||||
list.add(#default_skin);
|
||||
add_filesnames_into_the_list();
|
||||
if (active_skin==-1) && (ESBYTE[#previous_skin])
|
||||
{
|
||||
for (j=0; j<select_list.count; j++) {
|
||||
if (streq(list.get(j), #previous_skin)) {
|
||||
active_skin = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
select_list.cur_y = active_skin;
|
||||
} else {
|
||||
select_list.count++;
|
||||
list.add(#default_wallp);
|
||||
add_filesnames_into_the_list();
|
||||
if (active_wallpaper==-1) && (ESBYTE[#previous_wallp]=='\\')
|
||||
{
|
||||
for (j=0; j<select_list.count; j++) {
|
||||
if (streq(list.get(j), #previous_wallp+4)) {
|
||||
active_wallpaper = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
select_list.cur_y = active_wallpaper;
|
||||
}
|
||||
|
||||
if (!select_list.count) notify(T_NO_FILES);
|
||||
if (select_list.cur_y>SL_VISIBLE) {
|
||||
select_list.first = -SL_VISIBLE/2 + select_list.cur_y;
|
||||
}
|
||||
select_list.CheckDoesValuesOkey();
|
||||
if (LIST_W) draw_window();
|
||||
}
|
||||
|
||||
void SelectList_DrawLine(dword i)
|
||||
{
|
||||
int draw_y = i*SELECT_LIST_ITEMH+PANEL_H;
|
||||
int i_abs = select_list.first + i;
|
||||
dword text_color = 0xFFFfff;
|
||||
dword bg_color = 0x000000;
|
||||
char filename_buf[PATHLEN];
|
||||
char* filename = #filename_buf;
|
||||
|
||||
strcpy(filename, list.get(i_abs));
|
||||
if (EAX = strrchr(filename,'/')) filename += EAX;
|
||||
if (ESBYTE[filename]=='T') && (ESBYTE[filename+1]=='_') filename+=2;
|
||||
EAX = math.min(strrchr(filename,'.')-1, LIST_W - 24 / 8);
|
||||
if(EAX) ESBYTE[filename+EAX] = '\0';
|
||||
|
||||
//save current item for tab change
|
||||
switch(tabs.active_tab) {
|
||||
CASE TAB_SKINS:
|
||||
active_skin = select_list.cur_y;
|
||||
if (!i_abs) filename = T_DEFAULT;
|
||||
BREAK;
|
||||
CASE TAB_WALLPAPERS:
|
||||
active_wallpaper = select_list.cur_y;
|
||||
if (!i_abs) filename = T_DEFAULT;
|
||||
BREAK;
|
||||
CASE TAB_SCREENSAVERS:
|
||||
active_screensaver = select_list.cur_y;
|
||||
if (!i_abs) filename = T_NO_SS;
|
||||
}
|
||||
|
||||
if (select_list.cur_y == i_abs) {
|
||||
text_color = sc.button;
|
||||
bg_color = sc.button_text;
|
||||
}
|
||||
DrawBar(select_list.x, draw_y, LIST_W, SELECT_LIST_ITEMH, text_color);
|
||||
WriteText(select_list.x+12,draw_y+select_list.text_y,select_list.font_type,bg_color, filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GetIniSettings()
|
||||
{
|
||||
ini.section = "style";
|
||||
ini.GetString("default_skin", #default_skin, PATHLEN, 0);
|
||||
ini.GetString("default_wallp", #default_wallp, PATHLEN, 0);
|
||||
ini.GetString("skin", #previous_skin, PATHLEN, 0);
|
||||
ini.GetString("bg_param", #previous_wallp, PATHLEN, 0);
|
||||
|
||||
ini.section = "screensaver";
|
||||
ss_timeout.position = ini.GetInt("timeout", 10) - 1;
|
||||
ini.GetString("available", #ss_available, sizeof(ss_available), 0);
|
||||
ini.GetString("program", #previous_ss, PATHLEN, 0);
|
||||
}
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// EVENTS //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void EventTabSkinsClick()
|
||||
{
|
||||
miniprintf(#folder_path, "%s/res/skins", get_real_kolibrios_path());
|
||||
Open_Dir();
|
||||
}
|
||||
|
||||
void EventTabWallpappersClick()
|
||||
{
|
||||
if (opendir_path) {
|
||||
strcpy(#folder_path, #opendir_path);
|
||||
} else {
|
||||
miniprintf(#folder_path, "%s/res/wallpapers", get_real_kolibrios_path());
|
||||
}
|
||||
Open_Dir();
|
||||
}
|
||||
|
||||
void EventTabScreensaverClick()
|
||||
{
|
||||
dword j;
|
||||
char ssmas[sizeof(ss_available)];
|
||||
list.drop();
|
||||
select_list.ClearList();
|
||||
|
||||
select_list.count++;
|
||||
list.add("");
|
||||
|
||||
strcpy(#ssmas, #ss_available);
|
||||
do {
|
||||
j = strrchr(#ssmas, '|');
|
||||
if (ssmas[j]=='/') {
|
||||
strcpy(#param, #ssmas + j);
|
||||
} else {
|
||||
miniprintf(#param, "/sys/%s", #ssmas + j);
|
||||
}
|
||||
list.add(#param);
|
||||
ESBYTE[#ssmas + j - 1] = '\0';
|
||||
select_list.count++;
|
||||
} while (j);
|
||||
|
||||
if (active_screensaver == -1) && (ESBYTE[#previous_ss]) {
|
||||
for (j=0; j<select_list.count; j++) {
|
||||
if (strstr(list.get(j), #previous_ss)) active_screensaver = j;
|
||||
}
|
||||
}
|
||||
select_list.cur_y = active_screensaver;
|
||||
|
||||
if (LIST_W) draw_window();
|
||||
}
|
||||
|
||||
void EventDeleteFile()
|
||||
{
|
||||
if (select_list.cur_y) DeleteFile(list.get(select_list.cur_y)); //no not delete default
|
||||
Open_Dir();
|
||||
EventApply();
|
||||
}
|
||||
|
||||
void EventSelectWallpFolder()
|
||||
{
|
||||
o_dialog.type = 2; //select folder
|
||||
OpenDialog_start stdcall (#o_dialog);
|
||||
if (o_dialog.status) EventTabWallpappersClick();
|
||||
}
|
||||
|
||||
void EventSetWallpMode(dword _stretch, _titled, _auto)
|
||||
{
|
||||
optionbox_stretch.checked = _stretch;
|
||||
optionbox_tiled.checked = _titled;
|
||||
optionbox_auto.checked = _auto;
|
||||
optionbox_tiled.redraw();
|
||||
optionbox_stretch.redraw();
|
||||
optionbox_auto.redraw();
|
||||
EventApply();
|
||||
}
|
||||
|
||||
void EventApply()
|
||||
{
|
||||
char kivparam[4096+10];
|
||||
dword file_name = list.get(select_list.cur_y);
|
||||
if (tabs.active_tab==TAB_SKINS)
|
||||
{
|
||||
strcpy(#cur_skin_path, list.get(select_list.cur_y));
|
||||
SetSystemSkin(#cur_skin_path);
|
||||
MoveSize(OLD, OLD, OLD, WIN_H+4+GetSkinHeight());
|
||||
}
|
||||
if (tabs.active_tab==TAB_WALLPAPERS)
|
||||
{
|
||||
SelectList_Draw();
|
||||
miniprintf(#kivparam, "\\S__%s", list.get(select_list.cur_y));
|
||||
if (optionbox_tiled.checked) || (!select_list.cur_y) kivparam[1]='T';
|
||||
if (optionbox_auto.checked) {
|
||||
file_name += strrchr(file_name, '/');
|
||||
if (ESBYTE[file_name] == 'T') && (ESBYTE[file_name+1] == '_') {
|
||||
kivparam[1]='T';
|
||||
}
|
||||
}
|
||||
RunProgram("/sys/media/kiv", #kivparam);
|
||||
}
|
||||
if (tabs.active_tab==TAB_SCREENSAVERS)
|
||||
{
|
||||
SelectList_Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void EventOpenFile()
|
||||
{
|
||||
switch (tabs.active_tab) {
|
||||
case TAB_SKINS:
|
||||
RunProgram("/sys/skincfg", list.get(select_list.cur_y));
|
||||
break;
|
||||
case TAB_WALLPAPERS:
|
||||
RunProgram("/sys/media/kiv", list.get(select_list.cur_y));
|
||||
break;
|
||||
case TAB_SCREENSAVERS:
|
||||
if(select_list.cur_y) {
|
||||
KillProcessByName("@ss", MULTIPLE);
|
||||
RunProgram(list.get(select_list.cur_y), "@ss");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventExit()
|
||||
{
|
||||
if (get_real_kolibrios_path()) && (ESBYTE[#cur_skin_path]) {
|
||||
ini.section = "style";
|
||||
ini.SetString("skin", #cur_skin_path, strlen(#cur_skin_path));
|
||||
}
|
||||
ExitProcess();
|
||||
}
|
||||
|
||||
void EventSetSs()
|
||||
{
|
||||
dword cur_ss = list.get(select_list.cur_y);
|
||||
ini.section = "screensaver";
|
||||
ini.SetString("program", cur_ss, strlen(cur_ss));
|
||||
ini.SetInt("timeout", ss_timeout.position+1);
|
||||
RestartProcessByName("/sys/@ss", MULTIPLE);
|
||||
}
|
||||
|
||||
stop:
|
||||
|
||||
char folder_path[PATHLEN];
|
||||
char cur_skin_path[PATHLEN];
|
||||
|
||||
char default_skin[PATHLEN];
|
||||
char default_wallp[PATHLEN];
|
||||
|
||||
char previous_skin[PATHLEN];
|
||||
char previous_wallp[PATHLEN];
|
||||
char previous_ss[PATHLEN];
|
||||
@@ -1,5 +0,0 @@
|
||||
@c-- /D=LANG_ENG appearance.c
|
||||
@del *.
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
if not exist appearance ( @pause )
|
||||
@@ -1,5 +0,0 @@
|
||||
@c-- /D=LANG_RUS appearance.c
|
||||
@del *.
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
if not exist appearance ( @pause )
|
||||
@@ -1,106 +0,0 @@
|
||||
#ifdef LANG_RUS
|
||||
char t_skins[] = " Стиль окон";
|
||||
char t_wallpapers[] = " Обои";
|
||||
char t_screensaver[] = " Скринсейвер";
|
||||
?define WINDOW_HEADER "Настройки оформления"
|
||||
?define T_SELECT_FOLDER "Выбрать папку"
|
||||
?define T_PICTURE_MODE " Положение картинки "
|
||||
?define T_CHECKBOX_STRETCH "Растянуть"
|
||||
?define T_CHECKBOX_TILED "Замостить"
|
||||
?define T_CHECKBOX_AUTO "Автоматически"
|
||||
?define T_UPDATE_DOCK "Обновлять Dock-панель"
|
||||
?define T_NO_FILES "'Поддерживаемые файлы не найдены' -E"
|
||||
?define T_UI_PREVIEW " Пример компонентов "
|
||||
?define T_SS_TIMEOUT "Интервал в минутах: %i "
|
||||
?define T_SS_PREVIEW "Просмотр"
|
||||
?define T_SS_SET "Установить"
|
||||
?define T_NO_SS "[Выключен]"
|
||||
?define T_DEFAULT "[По умолчанию]"
|
||||
#else
|
||||
char t_skins[] = " Skins";
|
||||
char t_wallpapers[] = " Wallpapers";
|
||||
char t_screensaver[] = " Screensaver";
|
||||
?define WINDOW_HEADER "Appearance"
|
||||
?define T_SELECT_FOLDER "Select folder"
|
||||
?define T_PICTURE_MODE " Picture Mode "
|
||||
?define T_CHECKBOX_STRETCH "Stretch"
|
||||
?define T_CHECKBOX_TILED "Tiled"
|
||||
?define T_CHECKBOX_AUTO "Auto"
|
||||
?define T_UPDATE_DOCK "Update Dock"
|
||||
?define T_NO_FILES "'No supported files were found' -E"
|
||||
?define T_UI_PREVIEW " Components Preview "
|
||||
?define T_SS_TIMEOUT "Wait in minutes: %i "
|
||||
?define T_SS_PREVIEW "View"
|
||||
?define T_SS_SET "Set"
|
||||
?define T_NO_SS "[Disable]"
|
||||
?define T_DEFAULT "[Default]"
|
||||
#endif
|
||||
|
||||
#define WIN_W 560
|
||||
#define WIN_H 445
|
||||
#define LIST_W 260
|
||||
#define PANEL_H 50
|
||||
#define LP 6 //LIST_PADDING
|
||||
#define SL_VISIBLE WIN_H - PANEL_H - LP / SELECT_LIST_ITEMH
|
||||
|
||||
#define RIGHTx LP + LIST_W + TAB_P + 30
|
||||
#define RIGHTy PANEL_H
|
||||
#define RIGHTw WIN_W - RIGHTx - LP - TAB_P
|
||||
#define RIGHTh 215
|
||||
|
||||
enum {
|
||||
TAB_SKINS,
|
||||
TAB_WALLPAPERS,
|
||||
TAB_SCREENSAVERS
|
||||
};
|
||||
|
||||
enum {
|
||||
BASE_TAB_BUTTON_ID=3,
|
||||
BTN_SELECT_WALLP_FOLDER=10,
|
||||
BTN_TEST_SCREENSAVER,
|
||||
BTN_SET_SCREENSAVER
|
||||
};
|
||||
|
||||
_ini ini = { "/sys/settings/system.ini" };
|
||||
|
||||
char default_dir[] = "/sys";
|
||||
od_filter filter2 = { 8, "TXT\0\0" };
|
||||
|
||||
_tabs tabs = { -sizeof(t_skins)-sizeof(t_wallpapers)-sizeof(t_screensaver)
|
||||
-3*8+WIN_W - TAB_P / 2, LP, NULL, BASE_TAB_BUTTON_ID };
|
||||
|
||||
scroll_bar ss_timeout = { RIGHTw-19,RIGHTx,15,RIGHTy+25,0,3,89,10,0,0xFFFfff,
|
||||
0xBBBbbb,0xeeeeee};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void sort_by_name(int a, b) // for the first call: a = 0, b = sizeof(mas) - 1
|
||||
{
|
||||
int j;
|
||||
int isn = a;
|
||||
if (a >= b) return;
|
||||
for (j = a; j <= b; j++) {
|
||||
if (strcmpi(io.dir.position(ESDWORD[j*4+fmas]), io.dir.position(ESDWORD[b*4+fmas]))<=0) {
|
||||
ESDWORD[isn*4+fmas] >< ESDWORD[j*4+fmas];
|
||||
isn++;
|
||||
}
|
||||
}
|
||||
sort_by_name(a, isn-2);
|
||||
sort_by_name(isn, b);
|
||||
}
|
||||
|
||||
dword get_real_kolibrios_path()
|
||||
{
|
||||
char real_kolibrios_path[256];
|
||||
if (!dir_exists("/kolibrios")) return 0;
|
||||
SetCurDir("/kolibrios");
|
||||
GetCurDir(#real_kolibrios_path, sizeof(real_kolibrios_path));
|
||||
return #real_kolibrios_path;
|
||||
}
|
||||
|
||||
void SelectList_LineChanged()
|
||||
{
|
||||
EventApply();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
checkbox checkbox1 = { "Checkbox", true };
|
||||
more_less_box spinbox1 = { 23, 0, 999, "SpinBox" };
|
||||
edit_box edit_cmm = {180,NULL,NULL,0xffffff,0x94AECE,0xFFFfff,0xffffff,
|
||||
0x10000000,sizeof(param)-2,#param,0, 0b};
|
||||
char st_str[16];
|
||||
edit_box edit_st = {180,NULL,NULL,0xffffff,0x94AECE,0xFFFfff,0xffffff,
|
||||
0x10000000,sizeof(st_str)-2,#st_str,0, 0b};
|
||||
|
||||
|
||||
void DrawUiElementsPreview(dword x,y,h)
|
||||
{
|
||||
incn y2;
|
||||
spinbox1.draw(x, y2.set(y+30));
|
||||
WriteText(x, y2.inc(30), 0x90, sc.work_text, "C-- Edit");
|
||||
DrawEditBoxPos(x, y2.inc(20), #edit_cmm);
|
||||
WriteText(x, y2.inc(35), 0x90, sc.work_text, "Standard Edit");
|
||||
DrawStEditBoxPos(x, y2.inc(20), #edit_st);
|
||||
DrawStandartCaptButton(x, y+h-40, GetFreeButtonId(), "Button1");
|
||||
DrawStandartCaptButton(x+100, y+h-40, GetFreeButtonId(), "Button2");
|
||||
}
|
||||
|
||||
:void DrawStEditBoxPos(dword x,y, edit_box_pointer)
|
||||
{
|
||||
dword c_inactive = MixColors(sc.line, sc.work, 128);
|
||||
dword c_active = MixColors(sc.line, 0, 128);
|
||||
ESI = edit_box_pointer;
|
||||
ESI.edit_box.left = x;
|
||||
ESI.edit_box.top = y;
|
||||
ESI.edit_box.border_color = c_inactive;
|
||||
ESI.edit_box.focus_border_color = c_active;
|
||||
edit_box_draw stdcall (edit_box_pointer);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("barscfg.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "barscfg.com")
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 400 B |
Binary file not shown.
Binary file not shown.
@@ -1,317 +0,0 @@
|
||||
#define MEMSIZE 1024*40
|
||||
#include "..\lib\kolibri.h"
|
||||
#include "..\lib\strings.h"
|
||||
#include "..\lib\mem.h"
|
||||
#include "..\lib\fs.h"
|
||||
#include "..\lib\dll.h"
|
||||
#include "..\lib\gui.h"
|
||||
|
||||
#include "..\lib\obj\libini.h"
|
||||
#include "..\lib\obj\box_lib.h"
|
||||
|
||||
#include "..\lib\patterns\restart_process.h"
|
||||
|
||||
#ifdef LANG_RUS
|
||||
?define WINDOW_TITLE "Настройки панели задач и Дока"
|
||||
?define TASK_FRAME_T " Панель задач "
|
||||
?define DOCK_FRAME_T " Док "
|
||||
?define MIN_LEFT_BUTTON "Кнопка скрытия слева"
|
||||
?define MIN_RIGHT_BUTTON "Кнопка скрытия справа"
|
||||
?define SOFTEN_UP "Сглаживание сверху"
|
||||
?define SOFTEN_DOWN "Сглаживание снизу"
|
||||
?define CLOCK "Часы"
|
||||
?define CPU_USAGE "Загрузка ЦП"
|
||||
?define CHANGE_LANG "Язык ввода"
|
||||
?define MENU_BUTTON "Кнопка меню"
|
||||
?define PANEL_HEIGHT "Высота панели"
|
||||
?define SOFTEN_HEIGHT "Высота сглаживания"
|
||||
?define BUTTON_OFFSET "Поле вокруг кнопок"
|
||||
?define FSIZE "Режим панели"
|
||||
?define ASHOW "Не скрывать"
|
||||
?define CHANGE_POS "Нажмите на изображение для смены позиции"
|
||||
#else
|
||||
?define WINDOW_TITLE "Taskbar and Docky configuration"
|
||||
?define TASK_FRAME_T " Taskbar "
|
||||
?define DOCK_FRAME_T " Docky "
|
||||
?define MIN_LEFT_BUTTON "Min Left Button"
|
||||
?define MIN_RIGHT_BUTTON "Min Right Button"
|
||||
?define SOFTEN_UP "Soften Up"
|
||||
?define SOFTEN_DOWN "Soften Down"
|
||||
?define CLOCK "Clock"
|
||||
?define CPU_USAGE "Cpu Usage"
|
||||
?define CHANGE_LANG "Change Language"
|
||||
?define MENU_BUTTON "Menu Button"
|
||||
?define PANEL_HEIGHT "Panel Height"
|
||||
?define SOFTEN_HEIGHT "Soften Height"
|
||||
?define BUTTON_OFFSET "Button Offset"
|
||||
?define FSIZE "Full width"
|
||||
?define ASHOW "Always show"
|
||||
?define CHANGE_POS "Click on image to change position"
|
||||
#endif
|
||||
|
||||
char taskbar_ini_path[] = "/sys/settings/taskbar.ini";
|
||||
_ini taskbar_flags_ini = { #taskbar_ini_path, "Flags" };
|
||||
_ini taskbar_vars_ini = { #taskbar_ini_path, "Variables" };
|
||||
|
||||
_ini docky_ini = { "/sys/settings/docky.ini", "@" };
|
||||
|
||||
#define PIMG_W 37
|
||||
#define PIMG_H 27 //27*5
|
||||
unsigned char panels_img_data[] = FROM "bars_8b.raw";
|
||||
dword panels_img_pal[] = {
|
||||
0x00405D74,0x0084FC84,0x00FAFAFA,0x0000B400,
|
||||
0x00E4E4E4,0x008C9B9C,0x000212FD,0x00D8DEDF,
|
||||
0x00585C5D,0x0085B7E0,0x009EC6E7,0x0094C0E5,
|
||||
0x00CB8800,0x00CE3D9E,0x00D20404,0x00485966
|
||||
};
|
||||
|
||||
proc_info Form;
|
||||
|
||||
enum { BTN_TB_ATTACHEMENT=100, BTN_DOCKY_ATTACHEMENT=200 };
|
||||
enum { TASKBAR, DOCKY };
|
||||
|
||||
more_less_box tbPanelHeight = { NULL, 6, 99, PANEL_HEIGHT };
|
||||
more_less_box tbSoftenHeight = { NULL, 0, 99, SOFTEN_HEIGHT };
|
||||
more_less_box tbButtonOffset = { NULL, 0, 99, BUTTON_OFFSET };
|
||||
|
||||
checkbox taskbar_on = 0;
|
||||
checkbox docky_on = 0;
|
||||
|
||||
int tbAttachment;
|
||||
checkbox tbSoftenUp = { SOFTEN_UP };
|
||||
checkbox tbClock = { CLOCK };
|
||||
checkbox tbSoftenDown = { SOFTEN_DOWN };
|
||||
checkbox tbCpuUsage = { CPU_USAGE };
|
||||
checkbox tbMinLeftButton = { MIN_LEFT_BUTTON };
|
||||
checkbox tbChangeLang = { CHANGE_LANG };
|
||||
checkbox tbMinRightButton = { MIN_RIGHT_BUTTON };
|
||||
checkbox tbMenuButton = { MENU_BUTTON };
|
||||
checkbox dkFsize = { FSIZE };
|
||||
checkbox dkAshow = { ASHOW };
|
||||
|
||||
int dkLocation=0;
|
||||
checkbox tbRunApplButton;
|
||||
checkbox tbClnDeskButton;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
dword id;
|
||||
|
||||
load_dll(libini, #lib_init,1);
|
||||
load_dll(boxlib, #box_lib_init,0);
|
||||
|
||||
LoadCfg();
|
||||
|
||||
loop() switch(@WaitEvent())
|
||||
{
|
||||
case evButton:
|
||||
id = @GetButtonID();
|
||||
if (1==id) @ExitProcess();
|
||||
|
||||
if (taskbar_on.checked) EventTaskbarProcessButton(id);
|
||||
if (docky_on.checked) EventDockyProcessButton(id);
|
||||
|
||||
if (taskbar_on.click(id)) {
|
||||
IF (taskbar_on.checked == true) RunProgram("/sys/@taskbar", 0);
|
||||
ELSE KillProcessByName("@TASKBAR", SINGLE);
|
||||
DrawWindowContent();
|
||||
}
|
||||
if (docky_on.click(id)) {
|
||||
IF (docky_on.checked == true) {
|
||||
dkLocation = 2;
|
||||
SaveSettingsAndRestartProcess(DOCKY);
|
||||
} ELSE {
|
||||
KillProcessByName("@DOCKY", SINGLE);
|
||||
}
|
||||
DrawWindowContent();
|
||||
}
|
||||
break;
|
||||
|
||||
case evKey:
|
||||
if (@GetKeyScancode() == SCAN_CODE_ESC) ExitProcess();
|
||||
break;
|
||||
|
||||
case evReDraw:
|
||||
sc.get();
|
||||
DefineAndDrawWindow(130, 150, 465, 398 + skin_h, 0x34, sc.work, WINDOW_TITLE, 0);
|
||||
GetProcessInfo(#Form, SelfInfo);
|
||||
if (Form.status_window&ROLLED_UP) break;
|
||||
DrawWindowContent();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPanelsImage(dword y, n)
|
||||
{
|
||||
PutPaletteImage(n * PIMG_W * PIMG_H + #panels_img_data, PIMG_W, PIMG_H, 22, y, 8, #panels_img_pal);
|
||||
}
|
||||
|
||||
void SetDisabledMode()
|
||||
{
|
||||
EAX = taskbar_on.checked ^ 1;
|
||||
tbSoftenUp.disabled =
|
||||
tbSoftenDown.disabled =
|
||||
tbMinLeftButton.disabled =
|
||||
tbMinRightButton.disabled =
|
||||
tbRunApplButton.disabled =
|
||||
tbClnDeskButton.disabled =
|
||||
tbClock.disabled =
|
||||
tbCpuUsage.disabled =
|
||||
tbChangeLang.disabled =
|
||||
tbMenuButton.disabled =
|
||||
tbPanelHeight.disabled =
|
||||
tbSoftenHeight.disabled =
|
||||
tbButtonOffset.disabled =
|
||||
tbButtonOffset.disabled = EAX;
|
||||
//
|
||||
dkFsize.disabled =
|
||||
dkAshow.disabled = docky_on.checked ^ 1;
|
||||
}
|
||||
|
||||
void DrawWindowContent()
|
||||
{
|
||||
#define PD 10
|
||||
dword frame_y;
|
||||
word win_center_x = Form.cwidth / 2 + 20;
|
||||
incn y;
|
||||
int i;
|
||||
|
||||
SetDisabledMode();
|
||||
|
||||
frame_y = 15;
|
||||
y.n = frame_y;
|
||||
DefineButton(22, y.inc(18), PIMG_W-1, PIMG_H-1, 100 + BT_HIDE, 0);
|
||||
DrawPanelsImage(y.n, tbAttachment);
|
||||
WriteTextWithBg(68, y.inc(7), 0xD0, sc.work_text, CHANGE_POS, sc.work);
|
||||
tbSoftenUp.draw(22, y.inc(35));
|
||||
tbClock.draw(win_center_x, y.n);
|
||||
tbSoftenDown.draw(22, y.inc(24));
|
||||
tbCpuUsage.draw(win_center_x, y.n);
|
||||
tbMinLeftButton.draw(22, y.inc(24));
|
||||
tbChangeLang.draw(win_center_x, y.n);
|
||||
tbMinRightButton.draw(22, y.inc(24));
|
||||
tbMenuButton.draw(win_center_x, y.n);
|
||||
tbPanelHeight.draw(22, y.inc(28));
|
||||
tbSoftenHeight.draw(22, y.inc(32));
|
||||
tbButtonOffset.draw(22, y.inc(32));
|
||||
DrawFrame(PD, frame_y, Form.cwidth-PD-PD, y.inc(32)-frame_y, TASK_FRAME_T);
|
||||
taskbar_on.draw(22, frame_y-7);
|
||||
//DOCKY
|
||||
frame_y = calc(y.inc(20));
|
||||
DefineButton(22, y.inc(18), PIMG_W-1, PIMG_H-1, 200 + BT_HIDE, 0);
|
||||
if (!dkLocation) i=2; else i=dkLocation;
|
||||
DrawPanelsImage(y.n, i+1);
|
||||
WriteTextWithBg(68, y.inc(7), 0xD0, sc.work_text, CHANGE_POS, sc.work);
|
||||
dkFsize.draw(22, y.inc(35));
|
||||
dkAshow.draw(win_center_x, y.n);
|
||||
DrawFrame(PD, frame_y, Form.cwidth-PD-PD, Form.cheight-frame_y-PD, DOCK_FRAME_T);
|
||||
docky_on.draw(22, frame_y-7);
|
||||
}
|
||||
|
||||
void LoadCfg()
|
||||
{
|
||||
tbAttachment = taskbar_flags_ini.GetInt("Attachment", 1);
|
||||
tbSoftenUp.checked = taskbar_flags_ini.GetInt("SoftenUp", 1);
|
||||
tbSoftenDown.checked = taskbar_flags_ini.GetInt("SoftenDown", 1);
|
||||
tbMinLeftButton.checked = taskbar_flags_ini.GetInt("MinLeftButton", 1);
|
||||
tbMinRightButton.checked = taskbar_flags_ini.GetInt("MinRightButton", 1);
|
||||
tbClock.checked = taskbar_flags_ini.GetInt("Clock", 1);
|
||||
tbCpuUsage.checked = taskbar_flags_ini.GetInt("CpuUsage", 1);
|
||||
tbChangeLang.checked = taskbar_flags_ini.GetInt("ChangeLang", 1);
|
||||
tbMenuButton.checked = taskbar_flags_ini.GetInt("MenuButton", 1);
|
||||
tbPanelHeight.value = taskbar_vars_ini.GetInt("PanelHeight", 28);
|
||||
tbSoftenHeight.value = taskbar_vars_ini.GetInt("SoftenHeight", 4);
|
||||
tbButtonOffset.value = taskbar_vars_ini.GetInt("ButtonTopOffset", 3);
|
||||
tbButtonOffset.value = taskbar_vars_ini.GetInt("ButtonBotOffset", 3);
|
||||
|
||||
dkLocation = docky_ini.GetInt("location", 0);
|
||||
dkFsize.checked = docky_ini.GetInt("fsize", 0);
|
||||
dkAshow.checked = docky_ini.GetInt("ashow", 0);
|
||||
|
||||
taskbar_on.checked = CheckProcessExists("@TASKBAR");
|
||||
docky_on.checked = CheckProcessExists("@DOCKY");
|
||||
}
|
||||
|
||||
void SaveSettingsAndRestartProcess(byte panel_type)
|
||||
{
|
||||
if (panel_type==TASKBAR) {
|
||||
taskbar_flags_ini.SetInt("Attachment", tbAttachment);
|
||||
taskbar_flags_ini.SetInt("SoftenUp", tbSoftenUp.checked);
|
||||
taskbar_flags_ini.SetInt("SoftenDown", tbSoftenDown.checked);
|
||||
taskbar_flags_ini.SetInt("MinLeftButton", tbMinLeftButton.checked);
|
||||
taskbar_flags_ini.SetInt("MinRightButton", tbMinRightButton.checked);
|
||||
taskbar_flags_ini.SetInt("RunApplButton", tbRunApplButton.checked);
|
||||
taskbar_flags_ini.SetInt("ClnDeskButton", tbClnDeskButton.checked);
|
||||
taskbar_flags_ini.SetInt("Clock", tbClock.checked);
|
||||
taskbar_flags_ini.SetInt("CpuUsage", tbCpuUsage.checked);
|
||||
taskbar_flags_ini.SetInt("ChangeLang", tbChangeLang.checked);
|
||||
taskbar_flags_ini.SetInt("MenuButton", tbMenuButton.checked);
|
||||
taskbar_vars_ini.SetInt("PanelHeight", tbPanelHeight.value);
|
||||
taskbar_vars_ini.SetInt("SoftenHeight", tbSoftenHeight.value);
|
||||
taskbar_vars_ini.SetInt("ButtonTopOffset", tbButtonOffset.value);
|
||||
taskbar_vars_ini.SetInt("ButtonBottOffset", tbButtonOffset.value);
|
||||
}
|
||||
if (panel_type==DOCKY) {
|
||||
if (!docky_on.checked) {
|
||||
docky_ini.SetInt("location", 0);
|
||||
} else {
|
||||
docky_ini.SetInt("location", dkLocation);
|
||||
}
|
||||
docky_ini.SetInt("fsize", dkFsize.checked);
|
||||
docky_ini.SetInt("ashow", dkAshow.checked);
|
||||
}
|
||||
RestartProcess(panel_type);
|
||||
}
|
||||
|
||||
void RestartProcess(byte panel_type)
|
||||
{
|
||||
dword proc_name1;
|
||||
if (panel_type == TASKBAR)
|
||||
{
|
||||
RestartProcessByName("/sys/@taskbar", SINGLE);
|
||||
pause(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestartProcessByName("/sys/@docky", SINGLE);
|
||||
pause(120);
|
||||
}
|
||||
GetProcessInfo(#Form, SelfInfo);
|
||||
ActivateWindow(GetProcessSlot(Form.ID));
|
||||
}
|
||||
|
||||
void EventTaskbarProcessButton(dword id)
|
||||
{
|
||||
if (BTN_TB_ATTACHEMENT == id) {
|
||||
tbAttachment ^= 1;
|
||||
DrawWindowContent();
|
||||
SaveSettingsAndRestartProcess(TASKBAR);
|
||||
}
|
||||
if (tbSoftenUp.click(id)) || (tbSoftenDown.click(id))
|
||||
|| (tbMinLeftButton.click(id)) || (tbMinRightButton.click(id))
|
||||
|| (tbRunApplButton.click(id)) || (tbClnDeskButton.click(id)) {
|
||||
SaveSettingsAndRestartProcess(TASKBAR);
|
||||
}
|
||||
if (tbClock.click(id)) || (tbCpuUsage.click(id))
|
||||
|| (tbChangeLang.click(id)) || (tbMenuButton.click(id))
|
||||
|| (tbPanelHeight.click(id)) || (tbSoftenHeight.click(id))
|
||||
|| (tbButtonOffset.click(id)) {
|
||||
SaveSettingsAndRestartProcess(TASKBAR);
|
||||
}
|
||||
}
|
||||
|
||||
void EventDockyProcessButton(dword id)
|
||||
{
|
||||
if (BTN_DOCKY_ATTACHEMENT == id) {
|
||||
dkLocation++;
|
||||
if (dkLocation>4) dkLocation=1;
|
||||
DrawWindowContent();
|
||||
SaveSettingsAndRestartProcess(DOCKY);
|
||||
}
|
||||
if (dkFsize.click(id)) || (dkAshow.click(id)) {
|
||||
SaveSettingsAndRestartProcess(DOCKY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stop:
|
||||
@@ -1,6 +0,0 @@
|
||||
@c-- /D=LANG_ENG barscfg.c
|
||||
@pause
|
||||
@del barscfg
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
@c-- /D=LANG_RUS barscfg.c
|
||||
@pause
|
||||
@del barscfg
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("bbench.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "bbench.com")
|
||||
@@ -1,616 +0,0 @@
|
||||
//========================================================//
|
||||
// //
|
||||
// BirdBench - a modular system benchmark //
|
||||
// The window is a launcher: tick the tests you want, //
|
||||
// press Run - results open as an HTML report in //
|
||||
// WebView (clearer there than in the tiny window). //
|
||||
// //
|
||||
// Add a test : edit tests_cpu.h / tests_gpu.h / ... //
|
||||
// Add a rival : edit cpudb.h //
|
||||
// //
|
||||
//========================================================//
|
||||
|
||||
#define MEMSIZE 4096*1536 // ~6 MB heap (2+2 MB work buffers + canvas)
|
||||
|
||||
#include "../lib/kolibri.h" // must be first (sets entry point)
|
||||
#include "../lib/mem.h"
|
||||
#include "../lib/strings.h"
|
||||
#include "../lib/fs.h"
|
||||
#include "../lib/io.h"
|
||||
#include "../lib/gui.h"
|
||||
#include "../lib/system.h"
|
||||
#include "../lib/gui/checkbox.h"
|
||||
#include "../lib/gui/menu.h"
|
||||
|
||||
#include "bbench.h"
|
||||
#include "tests_cpu.h"
|
||||
#include "tests_gpu.h"
|
||||
#include "tests_disk.h"
|
||||
#include "cpudb.h"
|
||||
|
||||
//---------------- layout ----------------//
|
||||
#define PAD 16
|
||||
#define COL2_X 170 // second column (Graphics)
|
||||
#define COL3_X 328 // third column (Disk)
|
||||
#define HEADER_H 42
|
||||
#define ROW_H 22
|
||||
#define WIN_W GCV_W
|
||||
#define WIN_H GCV_H + HEADER_H
|
||||
|
||||
#define BUTTON_Y WIN_H - 62
|
||||
#define BUTTON_W 70
|
||||
#define BUTTON_H 24
|
||||
|
||||
#define STATUSBAR_Y WIN_H - 25
|
||||
|
||||
#define BAR_FULL 3000 // score that fills a full HTML bar
|
||||
|
||||
#define BTN_RUN 30
|
||||
#define BTN_ALL 33
|
||||
#define BTN_NONE 34
|
||||
#define BTN_DISK_DROP 39 // disk dropdown toggle
|
||||
#define MAX_DISKS 20
|
||||
#define BTN_SECT_BASE 50 // 50..52 section masters
|
||||
#define BTN_CHECK_BASE 60 // 60.. per-test checkboxes
|
||||
|
||||
checkbox cb; // reused as a renderer for every checkbox
|
||||
|
||||
byte t_enabled[MAX_TESTS];
|
||||
dword sums[SECT_NUM];
|
||||
dword cnts[SECT_NUM];
|
||||
|
||||
char sysinfo[] = "CPU: %d MHz RAM: %d MB Screen: %dx%d@%db";
|
||||
char revinfo[] = " BB Revision: %d";
|
||||
|
||||
//---------------- disk list (LMENU dropdown) ----------------//
|
||||
char disk_store[MAX_DISKS*24];
|
||||
dword disk_dirp[MAX_DISKS];
|
||||
int disk_count = 0;
|
||||
int disk_sel = 0;
|
||||
byte disk_menu_open = 0; // an LMENU popup is currently open
|
||||
char disk_menu[MAX_DISKS*26]; // "\n"-separated item list for /sys/develop/menu
|
||||
dword disk_drop_x, disk_drop_y;
|
||||
char probe_buf[16];
|
||||
|
||||
int DiskWritable(dword dir)
|
||||
{
|
||||
char pf[80];
|
||||
dword r;
|
||||
strcpy(#pf, dir); strcat(#pf, "/bbprobe.tmp");
|
||||
r = FileWrite(#pf, #probe_buf, 16);
|
||||
if (r==0) dk_delete(#pf);
|
||||
if (r==0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddDisk(dword dir)
|
||||
{
|
||||
dword slot;
|
||||
if (disk_count >= MAX_DISKS) return;
|
||||
slot = disk_count * 24; slot = slot + #disk_store;
|
||||
strcpy(slot, dir);
|
||||
disk_dirp[disk_count] = slot;
|
||||
disk_count++;
|
||||
}
|
||||
|
||||
void TryDisk(dword dir) { if (DiskWritable(dir)) AddDisk(dir); }
|
||||
|
||||
void ScanDisks() // enumerate real mounts under "/", keep writable
|
||||
{
|
||||
int i, j;
|
||||
dword nm, l;
|
||||
char base[48];
|
||||
char dig[2];
|
||||
byte c0, c1, skip;
|
||||
disk_count = 0;
|
||||
dig[1] = 0;
|
||||
io.dir.load("/", DIR_ONLYREAL);
|
||||
for (i=0; i<io.dir.count; i++) {
|
||||
nm = io.dir.position(i);
|
||||
c0 = DSBYTE[nm]; c1 = DSBYTE[nm+1];
|
||||
skip = 0;
|
||||
l = strlen(nm);
|
||||
if (l > 12) skip = 1; // path slots are fixed 24 bytes
|
||||
if (c0=='c') && (c1=='d') skip = 1; // CD (read-only)
|
||||
if (c0=='f') && (c1=='d') skip = 1; // floppy
|
||||
if (c0=='r') && (c1=='d') skip = 1; // ramdisk /rd (system)
|
||||
if (!skip) {
|
||||
// whole-disk FS (rare: unpartitioned media)
|
||||
strcpy(#base, "/"); strcat(#base, nm);
|
||||
TryDisk(#base);
|
||||
// probe partitions /1../9 - the writable one is NOT always #1
|
||||
// (e.g. #1 = EFI/NTFS-reserved, data partition = #2 or #3)
|
||||
for (j=1; j<=9; j++) {
|
||||
dig[0] = j + '0';
|
||||
strcpy(#base, "/"); strcat(#base, nm);
|
||||
strcat(#base, "/"); strcat(#base, #dig);
|
||||
TryDisk(#base);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disk_count < 1) AddDisk("/tmp0/1");
|
||||
disk_sel = 0;
|
||||
disk_dir = disk_dirp[0];
|
||||
disk_menu[0] = 0; // "\n"-joined paths for the LMENU app
|
||||
for (i=0; i<disk_count; i++) {
|
||||
strcat(#disk_menu, disk_dirp[i]);
|
||||
if (i < disk_count-1) strcat(#disk_menu, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
//---------------- helpers ----------------//
|
||||
void bench_exit() // single exit point: never leave bbtst.tmp behind
|
||||
{
|
||||
Disk_Cleanup();
|
||||
ExitProcess();
|
||||
}
|
||||
|
||||
void FlatButton(dword x, id, bg, tc, label)
|
||||
{
|
||||
DefineButton(x, BUTTON_Y, BUTTON_W, BUTTON_H - 1, id, bg);
|
||||
WriteText(-strlen(label)*8 + BUTTON_W / 2 + x,
|
||||
BUTTON_H - 16 / 2 + BUTTON_Y, 0x90, tc, label);
|
||||
}
|
||||
|
||||
//---------------- checkbox model ----------------//
|
||||
byte SectionAllOn(dword sect)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<t_count; i++) if (t_sect[i]==sect) && (!t_enabled[i]) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ToggleSection(dword sect)
|
||||
{
|
||||
int i;
|
||||
byte v;
|
||||
v = SectionAllOn(sect); v = v ^ 1;
|
||||
for (i=0; i<t_count; i++) if (t_sect[i]==sect) t_enabled[i] = v;
|
||||
}
|
||||
|
||||
void SetAll(byte v)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<t_count; i++) t_enabled[i] = v;
|
||||
}
|
||||
|
||||
//========================================================//
|
||||
// HTML export //
|
||||
//========================================================//
|
||||
#define ICON_CPU 48
|
||||
#define ICON_GPU 52
|
||||
#define ICON_DISK 50
|
||||
|
||||
#define EBUF_SIZE 16384 // report buffer; a full 48-test run needs ~6 KB
|
||||
#define BAR_W 26 // bar width in characters, same for every row
|
||||
|
||||
#define COL_NAME 20 // same columns for test and compare rows, so
|
||||
#define COL_SCORE 8 // numbers and bars line up down the whole page
|
||||
#define COL_INFO 16
|
||||
|
||||
// one copy of each colour; html_head repeats them for browsers that honour
|
||||
// <style> - WebView reads bg= straight off the tag
|
||||
char c_bar1[] = "#2c7be5"; char c_trk1[] = "#cdd2da";
|
||||
char c_bar2[] = "#4a90e2"; char c_trk2[] = "#e4e7ec";
|
||||
char c_cmp [] = "#8fb8e8";
|
||||
|
||||
dword ebuf = 0;
|
||||
dword epos = 0;
|
||||
char etmp[176];
|
||||
char epath[64];
|
||||
|
||||
void AppendBcd(dword dst, byte b) // BCD byte -> 2 ASCII digits
|
||||
{
|
||||
dword hi, lo;
|
||||
hi = b >> 4; hi = hi & 0xF;
|
||||
lo = b & 0xF;
|
||||
DSBYTE[dst] = hi + '0';
|
||||
DSBYTE[dst+1] = lo + '0';
|
||||
}
|
||||
|
||||
void BuildExportPath() // unique name from date + time
|
||||
{
|
||||
dword dt, tm, adr, v;
|
||||
EAX = 29; $int 0x40; dt = EAX; // fn 29: 0x00DDMMYY (BCD)
|
||||
EAX = 3; $int 0x40; tm = EAX; // fn 3: 0x00SSMMHH (BCD)
|
||||
strcpy(#epath, "/tmp0/1/bb_");
|
||||
adr = #epath; adr = adr + strlen(#epath);
|
||||
v = dt; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // YY
|
||||
v = dt >> 8; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // MM
|
||||
v = dt >> 16; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // DD
|
||||
DSBYTE[adr] = '_'; adr = adr + 1;
|
||||
v = tm; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // HH
|
||||
v = tm >> 8; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // MM
|
||||
v = tm >> 16; v = v & 0xFF; AppendBcd(adr, v); adr = adr + 2; // SS
|
||||
DSBYTE[adr] = 0;
|
||||
strcat(#epath, ".htm");
|
||||
}
|
||||
|
||||
void Hput(dword s)
|
||||
{
|
||||
dword l = strlen(s);
|
||||
if (epos + l >= EBUF_SIZE) return; // truncate the report, never the heap
|
||||
strcpy(ebuf+epos, s);
|
||||
epos = epos + l;
|
||||
}
|
||||
|
||||
void Hfield(dword s, dword width)
|
||||
{
|
||||
dword l = strlen(s);
|
||||
Hput(s);
|
||||
while (l < width) { Hput(" "); l++; }
|
||||
}
|
||||
|
||||
// one bar for test rows (max = BAR_FULL) and compare rows (max = fastest CPU)
|
||||
void Hbar(dword val, max, fillcol, trackcol)
|
||||
{
|
||||
dword filled, track, i;
|
||||
if (max < 1) max = 1;
|
||||
filled = muldiv(val, BAR_W, max); if (filled > BAR_W) filled = BAR_W;
|
||||
track = BAR_W - filled;
|
||||
Hput("<font bg="); Hput(fillcol); Hput(">");
|
||||
for (i=0; i<filled; i++) Hput(" ");
|
||||
Hput("</font><font bg="); Hput(trackcol); Hput(">");
|
||||
for (i=0; i<track; i++) Hput(" ");
|
||||
Hput("</font>\n");
|
||||
}
|
||||
|
||||
void ExportSection(dword sect, title, icon)
|
||||
{
|
||||
int i, r;
|
||||
dword whole, frac, barcol, trkcol;
|
||||
if (!SectionRan(sect)) return; // no completed test here -> no header at all
|
||||
if (sect==SECT_DISK) // show which disk was actually tested
|
||||
sprintf(#etmp, "<h3><kosicon n=%d><b>%s</b> (%s): %d</h3><blockquote>\n", icon, title, disk_dir, sect_score[sect]);
|
||||
else
|
||||
sprintf(#etmp, "<h3><kosicon n=%d><b>%s</b>: %d</h3><blockquote>\n", icon, title, sect_score[sect]);
|
||||
Hput(#etmp);
|
||||
r = 0;
|
||||
for (i=0; i<t_count; i++) {
|
||||
if (t_sect[i]==sect) {
|
||||
if (t_done[i]==2) { // not applicable here
|
||||
Hfield(t_name[i], COL_NAME);
|
||||
Hfield("skipped", COL_SCORE);
|
||||
Hput("\n");
|
||||
}
|
||||
if (t_done[i]==1) {
|
||||
whole = t_raw[i] / 100; frac = t_raw[i] % 100;
|
||||
if (r & 1) { barcol = #c_bar2; trkcol = #c_trk2; }
|
||||
else { barcol = #c_bar1; trkcol = #c_trk1; }
|
||||
Hfield(t_name[i], COL_NAME);
|
||||
sprintf(#etmp, "%d", t_score[i]); Hfield(#etmp, COL_SCORE);
|
||||
if (frac < 10) sprintf(#etmp, "%d.0%d %s", whole, frac, t_unit[i]);
|
||||
else sprintf(#etmp, "%d.%d %s", whole, frac, t_unit[i]);
|
||||
Hfield(#etmp, COL_INFO);
|
||||
Hbar(t_score[i], BAR_FULL, barcol, trkcol);
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Hput("</blockquote>\n");
|
||||
}
|
||||
|
||||
void CompareRow(dword name, mhz, score, maxscore, fillcol, trkcol)
|
||||
{
|
||||
char sb[20];
|
||||
Hfield(name, COL_NAME);
|
||||
sprintf(#sb, "%d", score); Hfield(#sb, COL_SCORE);
|
||||
sprintf(#sb, "%d MHz", mhz); Hfield(#sb, COL_INFO);
|
||||
Hbar(score, maxscore, fillcol, trkcol);
|
||||
}
|
||||
|
||||
#ifdef BB_CALIB
|
||||
// Ready-to-paste block: without it calibration means transcribing every
|
||||
// number by hand, so nobody does it and the REF_ values stay guesses.
|
||||
void ExportCalib()
|
||||
{
|
||||
int i;
|
||||
Hput("<h3><b>Calibration</b></h3><blockquote>\n");
|
||||
Hput("This machine's metrics. Put each one in the matching REF_ define to\n");
|
||||
Hput("score it 1000 everywhere, then bump BB_REVISION and re-measure cpudb.\n\n");
|
||||
for (i=0; i<t_count; i++) {
|
||||
if (t_done[i]==1) {
|
||||
Hfield(t_name[i], COL_NAME);
|
||||
sprintf(#etmp, "%d", t_raw[i]); Hput(#etmp);
|
||||
Hput("\n");
|
||||
}
|
||||
}
|
||||
if (SectionRan(SECT_CPU)) {
|
||||
sprintf(#etmp, "\ncpudb_add(\"CPU name here\", %d, %d, %d);\n",
|
||||
sys_cpu_mhz, sect_score[SECT_CPU], BB_REVISION);
|
||||
Hput(#etmp);
|
||||
}
|
||||
Hput("</blockquote>\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void ExportCompare()
|
||||
{
|
||||
int i;
|
||||
dword mx, thisc;
|
||||
thisc = sect_score[SECT_CPU];
|
||||
Hput("<h3><kosicon n=47><b>CPU compare</b></h3><blockquote>\n");
|
||||
mx = thisc;
|
||||
for (i=0; i<cpudb_count; i++) if (cpudb_score[i] > mx) mx = cpudb_score[i];
|
||||
if (mx < 1) mx = 1;
|
||||
CompareRow("This PC", sys_cpu_mhz, thisc, mx, #c_bar1, #c_trk1);
|
||||
for (i=0; i<cpudb_count; i++) {
|
||||
if (i < 8) CompareRow(cpudb_name[i], cpudb_mhz[i], cpudb_score[i], mx, #c_cmp, #c_trk2);
|
||||
}
|
||||
Hput("</blockquote>\n");
|
||||
}
|
||||
|
||||
// styles for Chrome/Firefox (WebView ignores <style>, uses bg= directly)
|
||||
char html_head[] = "</title><style>h3{margin:0}
|
||||
font{margin-bottom:1px;display:inline-block;}
|
||||
font[bg='#2c7be5']{background:#2c7be5}font[bg='#4a90e2']{background:#4a90e2}
|
||||
font[bg='#8fb8e8']{background:#8fb8e8}font[bg='#cdd2da']{background:#cdd2da}
|
||||
font[bg='#e4e7ec']{background:#e4e7ec}
|
||||
</style><body bgcolor=#ffffff><pre><h2>BirdBench results</h2>";
|
||||
|
||||
void ExportHTML()
|
||||
{
|
||||
dword sp, fname;
|
||||
if (!ebuf) ebuf = malloc(EBUF_SIZE);
|
||||
if (!ebuf) return;
|
||||
BuildExportPath(); // need the name for <title>
|
||||
sp = strrchr(#epath, '/');
|
||||
fname = #epath + sp; // -> "bb_YYMMDD_HHMMSS.htm"
|
||||
epos = 0;
|
||||
DSBYTE[ebuf] = 0;
|
||||
Hput("<html><title>"); Hput(fname);
|
||||
Hput(#html_head);
|
||||
Hput("<font color=#86868b>");
|
||||
sprintf(#etmp, #sysinfo, sys_cpu_mhz, sys_ram_mb, screen.w, screen.h, sys_bpp);
|
||||
Hput(#etmp);
|
||||
sprintf(#etmp, #revinfo, BB_REVISION);
|
||||
Hput(#etmp);
|
||||
Hput("</font>\n\n");
|
||||
ExportSection(SECT_CPU, "CPU", ICON_CPU); // each self-guards on t_done
|
||||
ExportSection(SECT_GPU, "Graphics", ICON_GPU);
|
||||
ExportSection(SECT_DISK, "Disk", ICON_DISK);
|
||||
if (SectionRan(SECT_CPU)) ExportCompare();
|
||||
#ifdef BB_CALIB
|
||||
ExportCalib();
|
||||
#endif
|
||||
Hput("</pre></body></html>");
|
||||
FileWrite(#epath, ebuf, epos);
|
||||
RunProgram("/sys/network/webview", #epath);
|
||||
}
|
||||
|
||||
//========================================================//
|
||||
// the panel //
|
||||
//========================================================//
|
||||
void DrawDiskButton(dword x, y) // combobox trigger (Eolite style) -> opens LMENU
|
||||
{
|
||||
#define DISK_BW 100
|
||||
#define DISK_BH 18
|
||||
dword ax;
|
||||
disk_drop_x = x; disk_drop_y = y;
|
||||
ax = x + DISK_BW - DISK_BH; // arrow-cell left
|
||||
// sunken field with a light background
|
||||
DrawRectangle3D(x, y, DISK_BW-1, DISK_BH, sc.dark, sc.light);
|
||||
DrawBar(x+1, y+1, DISK_BW-2, DISK_BH-1, sc.light);
|
||||
WriteText(x+5, y+3, 0x90, sc.work_text, disk_dirp[disk_sel]);
|
||||
// raised arrow button on the right
|
||||
DrawRectangle3D(x-1, y-1, DISK_BW+1, DISK_BH+2, sc.line, sc.line);
|
||||
DrawRectangle3D(ax-1, y-1, DISK_BH+1, DISK_BH+2, sc.line, sc.line);
|
||||
DrawRectangle3D(ax, y, DISK_BH-1, DISK_BH, sc.light, sc.dark);
|
||||
DrawBar(ax+1, y+1, DISK_BH-2, DISK_BH-1, sc.work);
|
||||
WriteText(ax+6, y+6, 0x80, sc.work_text, "\x19"); // CP866 down arrow
|
||||
DefineHiddenButton(x, y, DISK_BW-1, DISK_BH, BTN_DISK_DROP);
|
||||
}
|
||||
|
||||
dword DrawSectionChecks(dword sect, title, x, y)
|
||||
{
|
||||
int i;
|
||||
cb.disabled = 0;
|
||||
cb.text = title;
|
||||
cb.checked = SectionAllOn(sect);
|
||||
cb.id = BTN_SECT_BASE + sect;
|
||||
cb.draw(x, y);
|
||||
y = y + 30; // bigger gap after the master (the first)
|
||||
for (i=0; i<t_count; i++) {
|
||||
if (t_sect[i]==sect) {
|
||||
cb.disabled = 0;
|
||||
cb.text = t_name[i];
|
||||
cb.checked = t_enabled[i];
|
||||
cb.id = BTN_CHECK_BASE + i;
|
||||
cb.draw(x, y); // aligned with the master (no extra indent)
|
||||
y = y + ROW_H;
|
||||
}
|
||||
}
|
||||
DrawBar(x-1, HEADER_H+32, math.min(140, WIN_W-x-10), 1, sc.light); // line under the top (master) checkboxes
|
||||
DrawBar(x-1, HEADER_H+33, math.min(140, WIN_W-x-10), 1, sc.dark); // line under the top (master) checkboxes
|
||||
if (sect==SECT_DISK) { // dropdown under bottom checkbox
|
||||
DrawDiskButton(x, y+2); y = y + 24;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
void DrawPanel()
|
||||
{
|
||||
char line[96];
|
||||
// Icons
|
||||
draw_icon_32(67, 6, sc.work, 37); // CPU chip, centered over column 1
|
||||
draw_icon_32(225, 6, sc.work, 27); // Graphics card, over column 2
|
||||
draw_icon_32(362, 6, sc.work, 50); // Disk, over column 3
|
||||
// Main Checkboxes
|
||||
DrawSectionChecks(SECT_CPU, "CPU", PAD, HEADER_H + 10);
|
||||
DrawSectionChecks(SECT_GPU, "Graphics", COL2_X, HEADER_H + 10);
|
||||
DrawSectionChecks(SECT_DISK, "Disk", COL3_X, HEADER_H + 10);
|
||||
// Buttons
|
||||
FlatButton(PAD, BTN_ALL, sc.work, sc.work_text, "All");
|
||||
FlatButton(PAD + BUTTON_W + 9, BTN_NONE, sc.work, sc.work_text, "None");
|
||||
FlatButton(WIN_W - BUTTON_W - PAD, BTN_RUN, 0x4A90E2, 0xFFFFFF, "Run");
|
||||
// Foter
|
||||
DrawBar(0, STATUSBAR_Y, WIN_W, 1, sc.light);
|
||||
DrawBar(0, STATUSBAR_Y+1, WIN_W, 1, sc.dark);
|
||||
sprintf(#line, #sysinfo, sys_cpu_mhz, sys_ram_mb, screen.w, screen.h, sys_bpp);
|
||||
WriteText(PAD, STATUSBAR_Y+7, 0x90, sc.work_text, #line);
|
||||
// Disk open
|
||||
}
|
||||
|
||||
proc_info Form; // global: menu.h reads Form.left/top for LMENU
|
||||
|
||||
void draw_window()
|
||||
{
|
||||
dword wx, wy;
|
||||
sc.get();
|
||||
RefreshScreen();
|
||||
wx = 0; if (screen.w > WIN_W) { wx = screen.w - WIN_W; wx = wx/2; }
|
||||
wy = 0; if (screen.h > WIN_H) { wy = screen.h - WIN_H; wy = wy/2; }
|
||||
DefineAndDrawWindow(wx, wy, WIN_W+9, WIN_H+skin_h+4, 0x34, sc.work, "BirdBench", 0);
|
||||
GetProcessInfo(#Form, SelfInfo);
|
||||
DrawPanel();
|
||||
}
|
||||
|
||||
//---------------- run flow ----------------//
|
||||
char bench_caption[] = "This Bird is Benching";
|
||||
|
||||
void DrawRunScreen() // once per run: clear the body + draw the mascot
|
||||
{
|
||||
dword tx;
|
||||
DrawBar(0, 0, WIN_W, STATUSBAR_Y, sc.work);
|
||||
draw_icon_32(WIN_W-32/2, 96, sc.work, 121);
|
||||
tx = strlen(#bench_caption)*8; // 0x90 = 8x16 font
|
||||
tx = WIN_W - tx; tx = tx/2;
|
||||
WriteText(tx, 140, 0x90, sc.work_text, #bench_caption);
|
||||
}
|
||||
|
||||
void DrawRunStatus(dword name, idx, total, sect)
|
||||
{
|
||||
char msg[80];
|
||||
dword icon;
|
||||
icon = ICON_CPU;
|
||||
if (sect==SECT_GPU) icon = ICON_GPU;
|
||||
if (sect==SECT_DISK) icon = ICON_DISK;
|
||||
DrawBar(0, 0, WIN_W, HEADER_H, sc.work); // header only
|
||||
draw_icon_16w(PAD, 11, icon); // section icon, left of text
|
||||
sprintf(#msg, "Running %s (%d/%d)", name, idx, total);
|
||||
WriteText(PAD+24, 13, 0x90, sc.work_text, #msg);
|
||||
}
|
||||
|
||||
// drain events queued while a test was running; returns 1 if ESC = abort
|
||||
byte AbortRequested()
|
||||
{
|
||||
dword ev, id;
|
||||
byte stop = 0;
|
||||
loop() {
|
||||
ev = CheckEvent();
|
||||
if (!ev) break;
|
||||
if (ev==evButton) {
|
||||
id = GetButtonID();
|
||||
if (id==1) bench_exit(); // window X pressed mid-run
|
||||
}
|
||||
if (ev==evKey) {
|
||||
GetKeys();
|
||||
if (key_scancode==SCAN_CODE_ESC) stop = 1;
|
||||
}
|
||||
if (ev==evReDraw) { draw_window(); DrawRunScreen(); } // keep the run look
|
||||
}
|
||||
return stop;
|
||||
}
|
||||
|
||||
void RunSelected()
|
||||
{
|
||||
int i, idx, total;
|
||||
dword s, v;
|
||||
byte aborted;
|
||||
total = 0;
|
||||
for (i=0; i<t_count; i++) if (t_enabled[i]) total++;
|
||||
if (total < 1) return;
|
||||
for (s=0; s<SECT_NUM; s++) { sums[s] = 0; cnts[s] = 0; }
|
||||
for (i=0; i<t_count; i++) t_done[i] = 0;
|
||||
// occlusion skews fn13/fn7/fn38/fn4 (the kernel only draws visible
|
||||
// parts) - keep the window on top for the duration of the run
|
||||
SetWindowLayerBehaviour(-1, ZPOS_ALWAYS_TOP);
|
||||
DrawRunScreen(); // the mascot, once per run
|
||||
aborted = 0;
|
||||
idx = 0;
|
||||
for (i=0; i<t_count; i++) {
|
||||
if (t_enabled[i]) {
|
||||
if (AbortRequested()) { aborted = 1; break; }
|
||||
idx++;
|
||||
DrawRunStatus(t_name[i], idx, total, t_sect[i]);
|
||||
RunOne(i);
|
||||
if (t_done[i]==1) { // skipped carry no score
|
||||
s = t_sect[i];
|
||||
v = t_score[i]; if (v < 1) v = 1;
|
||||
sums[s] = sums[s] + ilog2_16(v); // geometric mean accumulator
|
||||
cnts[s] = cnts[s] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Disk_Cleanup(); // remove the 8 MB temp file
|
||||
SetWindowLayerBehaviour(-1, ZPOS_NORMAL);
|
||||
// section score = geomean of its tests (robust to single-test outliers)
|
||||
for (s=0; s<SECT_NUM; s++) {
|
||||
if (cnts[s] > 0) { v = sums[s] / cnts[s]; sect_score[s] = iexp2_16(v); }
|
||||
else sect_score[s] = 0;
|
||||
}
|
||||
draw_window();
|
||||
if (!aborted) ExportHTML(); // auto-open the report (ESC = silent abort)
|
||||
}
|
||||
|
||||
//---------------- events ----------------//
|
||||
void HandleButton(dword id)
|
||||
{
|
||||
if (id==1) bench_exit();
|
||||
if (id==BTN_DISK_DROP) { // open the LMENU popup below the combobox
|
||||
open_lmenu(disk_drop_x, disk_drop_y+DISK_BH+1, MENU_TOP_LEFT, disk_sel+1, #disk_menu);
|
||||
disk_menu_open = 1;
|
||||
return;
|
||||
}
|
||||
if (id==BTN_RUN) RunSelected();
|
||||
if (id==BTN_ALL) { SetAll(1); draw_window(); }
|
||||
if (id==BTN_NONE) { SetAll(0); draw_window(); }
|
||||
if (id>=BTN_SECT_BASE) && (id<BTN_SECT_BASE+SECT_NUM) {
|
||||
ToggleSection(id - BTN_SECT_BASE);
|
||||
draw_window();
|
||||
}
|
||||
if (id>=BTN_CHECK_BASE) && (id<BTN_CHECK_BASE+MAX_TESTS) {
|
||||
t_enabled[id-BTN_CHECK_BASE] ^= 1;
|
||||
draw_window();
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int i;
|
||||
dword click;
|
||||
GetSysInfo();
|
||||
if (!BenchAllocBuffers()) {
|
||||
notify("'BirdBench\nNot enough memory for the work buffers!' -E");
|
||||
ExitProcess();
|
||||
}
|
||||
cpudb_init();
|
||||
Register_CPU();
|
||||
Register_GPU();
|
||||
Register_DISK();
|
||||
ScanDisks();
|
||||
for (i=0; i<t_count; i++) t_enabled[i] = 1;
|
||||
|
||||
loop() switch(WaitEvent())
|
||||
{
|
||||
case evButton:
|
||||
HandleButton(GetButtonID());
|
||||
break;
|
||||
case evKey:
|
||||
GetKeys();
|
||||
if (key_scancode==SCAN_CODE_ESC) bench_exit();
|
||||
if (key_scancode==SCAN_CODE_ENTER) RunSelected();
|
||||
break;
|
||||
case evReDraw:
|
||||
if (disk_menu_open) { // an LMENU popup was opened
|
||||
click = get_menu_click();
|
||||
if (click) { // user picked a disk (1-based)
|
||||
disk_sel = click - 1;
|
||||
disk_dir = disk_dirp[disk_sel];
|
||||
}
|
||||
if (!menu_process_id) disk_menu_open = 0; // popup closed
|
||||
}
|
||||
draw_window();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
#ifndef INCLUDE_BENCH_H
|
||||
#define INCLUDE_BENCH_H
|
||||
//========================================================//
|
||||
// KolibriMark - benchmark engine //
|
||||
// Test registry, timing, scoring, system info. //
|
||||
// (No UI here - see kbench.c) //
|
||||
//========================================================//
|
||||
|
||||
#define SECT_CPU 0
|
||||
#define SECT_GPU 1
|
||||
#define SECT_DISK 2
|
||||
#define SECT_NUM 3
|
||||
|
||||
#define MAX_TESTS 48
|
||||
|
||||
//#define BB_CALIB // uncomment to add the calibration block to the report
|
||||
|
||||
#define BB_REVISION 1 // version of the tests + REF_ values, shown in the report
|
||||
#define BB_SKIP 0xFFFFFFFF // test cannot run here: no score, out of the geomean
|
||||
|
||||
// ---- shared work buffers ----
|
||||
#define GCV_X 0 // graphics canvas = window body (WIN_W/H tied to these)
|
||||
#define GCV_Y 42
|
||||
#define GCV_W 455 // wide enough for 3 columns of checkboxes
|
||||
#define GCV_H 240
|
||||
|
||||
#define CPY_BYTES 2097152 // 2 MB: copy/latency working set (> retro-era caches)
|
||||
|
||||
// buf_a: copy source, hash input, disk-write source (content never matters)
|
||||
// buf_b: copy dest, sieve + pointer-chase workspace (each test re-inits it)
|
||||
dword buf_a, buf_b, buf_canvas;
|
||||
|
||||
// ---- parallel-array registry (modular: RegisterTest appends) ----
|
||||
dword t_name [MAX_TESTS]; // -> name string
|
||||
dword t_unit [MAX_TESTS]; // -> unit string, e.g. "MB/s"
|
||||
dword t_fn [MAX_TESTS]; // -> test function (returns metric x100)
|
||||
dword t_ref [MAX_TESTS]; // reference metric x100 that scores 1000
|
||||
dword t_raw [MAX_TESTS]; // last measured metric x100
|
||||
dword t_score[MAX_TESTS]; // last computed score
|
||||
byte t_sect [MAX_TESTS];
|
||||
byte t_done [MAX_TESTS]; // 0 = not run, 1 = has a result, 2 = skipped
|
||||
int t_count = 0;
|
||||
|
||||
dword sect_score[SECT_NUM]; // aggregate score per section
|
||||
|
||||
void RegisterTest(dword sect, name, unit, ref, fn)
|
||||
{
|
||||
t_sect [t_count] = sect;
|
||||
t_name [t_count] = name;
|
||||
t_unit [t_count] = unit;
|
||||
t_ref [t_count] = ref;
|
||||
t_fn [t_count] = fn;
|
||||
t_raw [t_count] = 0;
|
||||
t_score[t_count] = 0;
|
||||
t_done [t_count] = 0;
|
||||
t_count++;
|
||||
}
|
||||
|
||||
byte SectionRan(dword sect) // true if any test here produced a result
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<t_count; i++) if (t_sect[i]==sect) && (t_done[i]==1) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---- 64-bit-safe a*b/c ----
|
||||
dword muldiv(dword a, b, c)
|
||||
{
|
||||
if (c<1) c = 1;
|
||||
EAX = a;
|
||||
ECX = b;
|
||||
$mul ecx
|
||||
ECX = c;
|
||||
$div ecx
|
||||
}
|
||||
|
||||
// ---- integer log2 / exp2 in 16.16 fixed point ----
|
||||
// Used for the geometric mean of section scores: with an arithmetic mean
|
||||
// one outlier test (VRAM write spans 2 orders of magnitude between WC and
|
||||
// non-WC machines) would dominate the whole section.
|
||||
// log2(1+f) ~ f + 0.343*f*(1-f), error < 0.5% after the exp2 round-trip.
|
||||
dword pw2tab[32]; // 2^n table (C-- has no variable shifts)
|
||||
|
||||
dword ilog2_16(dword s) // log2(s) in 16.16, s >= 1
|
||||
{
|
||||
dword e, m, x, c;
|
||||
if (s < 2) return 0;
|
||||
e = 0; m = s;
|
||||
while (m > 1) { m = m / 2; e++; }
|
||||
x = muldiv(s, 65536, pw2tab[e]);
|
||||
x = x - 65536; // fractional mantissa, 16.16
|
||||
c = 65536 - x;
|
||||
c = muldiv(x, c, 65536);
|
||||
c = muldiv(c, 22479, 65536); // 0.343 in 16.16
|
||||
x = x + c;
|
||||
e = e << 16;
|
||||
return e + x;
|
||||
}
|
||||
|
||||
dword iexp2_16(dword v) // 2^(v/65536), inverse of ilog2_16
|
||||
{
|
||||
dword e, f, c, m;
|
||||
e = v >> 16;
|
||||
f = v & 0xFFFF;
|
||||
c = 65536 - f;
|
||||
c = muldiv(f, c, 65536);
|
||||
c = muldiv(c, 22479, 65536);
|
||||
f = f - c;
|
||||
m = 65536 + f; // 2^frac in 16.16
|
||||
if (e > 30) return 0xFFFFFFFF;
|
||||
return muldiv(m, pw2tab[e], 65536);
|
||||
}
|
||||
|
||||
// ---- timing (system fn 26.9: 1/100 s counter) ----
|
||||
dword bench_t0;
|
||||
void BenchBegin() { bench_t0 = GetStartTime(); }
|
||||
dword BenchTicks() // elapsed 1/100 s, min 1
|
||||
{
|
||||
dword e = GetStartTime() - bench_t0;
|
||||
if (e < 1) e = 1;
|
||||
return e;
|
||||
}
|
||||
// count = amount processed in DISPLAY units; returns units/sec x100
|
||||
dword PerSecX100(dword count)
|
||||
{
|
||||
return muldiv(count, 10000, BenchTicks());
|
||||
}
|
||||
|
||||
// ---- call a registered test by pointer, return its metric x100 ----
|
||||
dword CallFn(dword fn)
|
||||
{
|
||||
ESI = fn;
|
||||
$call esi
|
||||
}
|
||||
|
||||
// ---- run one registered test ----
|
||||
void RunOne(int i)
|
||||
{
|
||||
dword raw = CallFn(t_fn[i]);
|
||||
if (raw == BB_SKIP) {
|
||||
t_raw[i] = 0;
|
||||
t_score[i] = 0;
|
||||
t_done[i] = 2;
|
||||
return;
|
||||
}
|
||||
t_raw[i] = raw;
|
||||
t_score[i] = muldiv(raw, 1000, t_ref[i]);
|
||||
t_done[i] = 1;
|
||||
}
|
||||
|
||||
// ---- allocate shared buffers + seed with data ----
|
||||
byte BenchAllocBuffers() // 0 = out of memory
|
||||
{
|
||||
dword i, n;
|
||||
buf_a = malloc(CPY_BYTES);
|
||||
buf_b = malloc(CPY_BYTES);
|
||||
buf_canvas = malloc(GCV_W*GCV_H*3);
|
||||
if (!buf_a) || (!buf_b) || (!buf_canvas) return 0;
|
||||
i = 0;
|
||||
while (i < CPY_BYTES) {
|
||||
ESDWORD[buf_a+i] = i;
|
||||
i += 4;
|
||||
}
|
||||
n = GCV_W*GCV_H; n = n*3;
|
||||
for (i=0; i<n; i++) DSBYTE[buf_canvas+i] = i; // gradient BBGGRR
|
||||
pw2tab[0] = 1;
|
||||
for (i=1; i<32; i++) { n = pw2tab[i-1]; pw2tab[i] = n + n; }
|
||||
return 1;
|
||||
}
|
||||
|
||||
//======================= system info =======================//
|
||||
dword sys_cpu_mhz;
|
||||
dword sys_ram_mb;
|
||||
dword sys_bpp; // current video mode bits per pixel
|
||||
|
||||
// re-read screen resolution + bpp (they change on a mode switch)
|
||||
void RefreshScreen()
|
||||
{
|
||||
dword d;
|
||||
EAX = 14; $int 0x40 // screen size: (w-1)<<16 + (h-1)
|
||||
d = EAX;
|
||||
screen.h = d & 0xFFFF; screen.h++;
|
||||
screen.w = d >> 16; screen.w++;
|
||||
EAX = 61; EBX = 2; $int 0x40 // fn 61.2 = bits per pixel
|
||||
sys_bpp = EAX;
|
||||
}
|
||||
|
||||
// RAM + CPU clock (fn 18.5). No CPUID/RDTSC -> fully 386-compatible (no
|
||||
// "CPU required: Pentium"). The processor is just labelled "CPU" in the UI.
|
||||
void GetSysInfo()
|
||||
{
|
||||
dword hz;
|
||||
sys_ram_mb = GetTotalRAM() / 1024;
|
||||
EAX = 18; EBX = 5; $int 0x40; // fn 18.5 = CPU clock rate, Hz
|
||||
hz = EAX;
|
||||
sys_cpu_mhz = hz / 1000000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
@del *.
|
||||
@..\c--\c--.exe bbench.c
|
||||
@rename *.com *.
|
||||
@del warning.txt
|
||||
if not exist bbench ( @pause )
|
||||
@@ -1,39 +0,0 @@
|
||||
#ifndef INCLUDE_CPUDB_H
|
||||
#define INCLUDE_CPUDB_H
|
||||
//========================================================//
|
||||
// CPU comparison database -- EDIT ME //
|
||||
// //
|
||||
// One line per reference CPU in cpudb_init(), copied straight //
|
||||
// from the Calibration block of a run on that machine. Entries //
|
||||
// measured under another BB_REVISION are hidden. //
|
||||
// The values below are placeholders - replace them. //
|
||||
//========================================================//
|
||||
|
||||
#define CPUDB_MAX 24
|
||||
dword cpudb_name [CPUDB_MAX];
|
||||
dword cpudb_mhz [CPUDB_MAX];
|
||||
dword cpudb_score[CPUDB_MAX];
|
||||
int cpudb_count = 0;
|
||||
|
||||
// entries from another revision are dropped: their numbers mean something else
|
||||
void cpudb_add(dword name, mhz, score, rev)
|
||||
{
|
||||
if (cpudb_count >= CPUDB_MAX) return;
|
||||
if (rev != BB_REVISION) return;
|
||||
cpudb_name [cpudb_count] = name;
|
||||
cpudb_mhz [cpudb_count] = mhz;
|
||||
cpudb_score[cpudb_count] = score;
|
||||
cpudb_count++;
|
||||
}
|
||||
|
||||
void cpudb_init()
|
||||
{
|
||||
cpudb_add("Intel Core i5-2400", 3100, 1600, 1);
|
||||
cpudb_add("AMD Athlon XP 2500+", 1833, 360, 1);
|
||||
cpudb_add("Intel Pentium 4", 2400, 300, 1);
|
||||
cpudb_add("Intel Pentium III", 1000, 180, 1);
|
||||
cpudb_add("Intel Atom N270", 1600, 420, 1);
|
||||
cpudb_add("VIA C7", 1200, 150, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,124 +0,0 @@
|
||||
# BirdBench
|
||||
|
||||
A small, modular system benchmark for KolibriOS, styled after Geekbench.
|
||||
Single-threaded (KolibriOS exposes no SMP to apps). 386-compatible
|
||||
(no CPUID/RDTSC — the MHz value comes from sysfn 18.5).
|
||||
|
||||
## Sections
|
||||
|
||||
* **CPU** — Integer, Floating Point, Memory Copy, Memory Latency,
|
||||
Prime Sieve, Hash (FNV-1a).
|
||||
Integer/Float run **4 independent chains** so superscalar CPUs (P5+) can
|
||||
pair/overlap them — a strictly serial chain would only measure latency.
|
||||
Float has no division on purpose: one fdiv (15–40+ cycles) would dominate
|
||||
the chain and the test would degenerate into an fdiv-latency meter.
|
||||
Memory Copy is a **forward** `rep movsd` over 2 MB (lib `memmov` copies
|
||||
backward when dst>src, which never hits the fast-string path on modern
|
||||
CPUs). Memory Latency is a serial pointer chase over a 2 MB random cycle
|
||||
(Sattolo shuffle) — defeats prefetch and cache, measures dependent-load
|
||||
latency; `100 / (Macc/s) = ns` per access.
|
||||
* **Graphics** — Fill (f13), Blit (f7), VRAM Read (f36), VRAM Write (gs:),
|
||||
Lines (f38), Text (f4).
|
||||
Fill/Blit = writes through the driver's blitter (may be HW-accelerated),
|
||||
VRAM Read (f36) = read-back, VRAM Write (gs:) = raw CPU `rep stosd` straight
|
||||
into the LFB via the GS selector — this one exposes write-combining (MTRR/PAT):
|
||||
no WC and it collapses ~10-50x. The report shows the current video mode —
|
||||
switch modes with the vidmode picker and re-run to compare VESA-LFB vs a
|
||||
native driver vs KMS at the same resolution.
|
||||
Before writing, the GS segment limit is checked with `lsl` — on banked-VGA
|
||||
modes (no LFB) the test skips instead of #GP-faulting. Color counters are
|
||||
masked to 24 bits: fn13 treats bit 31 as the gradient-fill flag and fn38
|
||||
treats bit 24 as the inversed-line flag — unmasked they silently switch the
|
||||
kernel to a different (slower) operation mid-test.
|
||||
Text draws **both kernel fonts** (6×9 and 8×16) and forces **subpixel font
|
||||
smoothing** for the duration (fn 48.9 saves the user's setting, fn 48.10
|
||||
sets/restores it) — the heaviest glyph path, so machines are compared on
|
||||
equal footing regardless of their smoothing setting.
|
||||
* **Disk** — Sequential write / read (2 MB ops) + Random write / read
|
||||
(4 KB blocks at fixed-seed random offsets in an 8 MB file, via fn 70
|
||||
positioned I/O) + **File System** (create 10 files + 10 folders, delete
|
||||
them all — metadata op/s, fn 70.2/70.9/70.8; names are pre-built so no
|
||||
sprintf lands in the timed loop). Folder support is probed first: not every
|
||||
writable FS driver implements fn 70.9 (exFAT has no CreateFolder at all) —
|
||||
there the test degrades to files-only instead of scoring 0. Pick the target
|
||||
disk in the UI — the report's Disk header shows which disk was tested. All
|
||||
disk rates are MiB/s.
|
||||
Temp files are deleted when the run finishes.
|
||||
NB: KolibriOS apps can't drop the FS cache, so on a real disk the random
|
||||
numbers reflect the FS small-op path (not raw seek/IOPS), and on the RAM
|
||||
disk random ≈ sequential (no seek penalty).
|
||||
|
||||
The window is a **launcher**: tick the tests you want (per-test checkboxes,
|
||||
per-section master checkbox, or All / None), pick a disk target, press **Run**.
|
||||
Only ticked tests run; **Esc aborts** between tests. During a run the window
|
||||
is forced always-on-top: the kernel only draws the visible parts of a window,
|
||||
so an occluded window would inflate the Graphics scores. When a run finishes,
|
||||
an HTML report is written to `/tmp0/1/bb_YYMMDD_HHMMSS.htm` (unique name) and
|
||||
**auto-opened in WebView**.
|
||||
|
||||
The report (not the window) shows the results: per-section score, one row per
|
||||
test with a colored bar (alternating shades) plus a gray/light-gray track, and
|
||||
a **CPU compare** chart of your score vs the CPUs in `cpudb.h` (with a MHz
|
||||
column; the compare bars line up with the test bars). Results are only
|
||||
in the web page — clearer there than in the small window.
|
||||
|
||||
Each test reports a raw throughput (MB/s, MPix/s, ...) and a *score*
|
||||
(1000 = the reference machine defined by the `REF_*` constants in the
|
||||
module). The section score is the **geometric mean** of its ticked tests'
|
||||
scores — a single outlier test (VRAM Write spans two orders of magnitude
|
||||
between WC and non-WC machines) can't dominate the section the way it
|
||||
would with an arithmetic mean.
|
||||
|
||||
## How to add a test
|
||||
|
||||
1. Open the section module (`tests_cpu.h`, `tests_gpu.h` or `tests_disk.h`).
|
||||
2. Write a function returning the metric ×100 (two decimals):
|
||||
|
||||
```c
|
||||
dword t_cpu_mytest()
|
||||
{
|
||||
dword c = 0;
|
||||
BenchBegin();
|
||||
do { /* one unit of work */ c++; } while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // units/sec ×100
|
||||
}
|
||||
```
|
||||
|
||||
`c` counts how many *display units* you processed (1 MB, 1 Mpixel,
|
||||
1 Kline, ...). The framework turns that into a per-second rate.
|
||||
3. Register it and give it a reference value:
|
||||
|
||||
```c
|
||||
#define REF_MYTEST 5000 // 50.00 units/s -> score 1000
|
||||
RegisterTest(SECT_CPU, "My Test", "u/s", REF_MYTEST, #t_cpu_mytest);
|
||||
```
|
||||
|
||||
That's it — it shows up in the list automatically.
|
||||
|
||||
## How to add a comparison CPU
|
||||
|
||||
Edit `cpudb.h`, add a line to `cpudb_init()`:
|
||||
|
||||
```c
|
||||
cpudb_add("Intel Core 2 Duo E8400", 3000, 520); // name, MHz, measured CPU score
|
||||
```
|
||||
|
||||
NB: any change to the test definitions invalidates previously measured
|
||||
db entries — re-measure them with the same binary you compare against.
|
||||
|
||||
## Build
|
||||
|
||||
Run `build.bat` (needs `../c--/c--.exe`). Output: `bbench`.
|
||||
|
||||
## Notes / calibration
|
||||
|
||||
* The `REF_*` constants are placeholders. Pick a machine as your baseline,
|
||||
run it, and set each `REF_*` to that machine's raw metric ×100 so it
|
||||
scores ~1000. Everything else scales relative to it.
|
||||
* All "MB" are MiB (2^20) across CPU, VRAM Write and Disk tests.
|
||||
* Random-I/O offsets and the latency chain use **fixed seeds** — every run
|
||||
and every machine gets the same access pattern (reproducibility).
|
||||
* On machines with a large L3 the 2 MB working set of Memory Copy/Latency
|
||||
measures the cache, not RAM — unavoidable at sizes that still fit
|
||||
retro-era boxes; scores stay comparable within an era.
|
||||
* Needs ~6 MB RAM (see `MEMSIZE`).
|
||||
@@ -1,188 +0,0 @@
|
||||
#ifndef INCLUDE_TESTS_CPU_H
|
||||
#define INCLUDE_TESTS_CPU_H
|
||||
//========================================================//
|
||||
// CPU test module. //
|
||||
// Each test returns its metric x100 (two decimals). //
|
||||
// To add a test: write t_cpu_xxx() then RegisterTest(). //
|
||||
//========================================================//
|
||||
|
||||
// reference metric x100 that should score 1000 (calibration)
|
||||
#define REF_INT 5000 // 50.00 MOps/s
|
||||
#define REF_FLOAT 2000 // 20.00 MFLOP/s
|
||||
#define REF_MEM 80000 // 800.00 MB/s
|
||||
#define REF_LAT 1000 // 10.00 Macc/s (= 100 ns per access)
|
||||
#define REF_SIEVE 3000 // 30.00 Mcell/s
|
||||
#define REF_HASH 10000 // 100.00 MB/s
|
||||
|
||||
#define CPY_MB 2 // CPY_BYTES in whole MiB (see bbench.h)
|
||||
#define LAT_N 524288 // nodes in the 2 MB pointer chain
|
||||
|
||||
dword cpu_sink;
|
||||
float cpu_fsink;
|
||||
dword lat_rnd;
|
||||
|
||||
// forward rep movsd block copy. NB: lib memmov() copies BACKWARD when
|
||||
// dst>src (std; rep movsd), which never hits the fast-string path on
|
||||
// modern CPUs and would understate them - so we do our own, forward.
|
||||
inline fastcall copy_fwd(EDI, ESI, ECX) // dst, src, bytes (mult of 4)
|
||||
{
|
||||
asm {
|
||||
CLD
|
||||
SHR ECX, 2
|
||||
REP MOVSD
|
||||
}
|
||||
}
|
||||
|
||||
void sieve1m(dword buf)
|
||||
{
|
||||
dword i, j;
|
||||
EDI = buf;
|
||||
EAX = 0;
|
||||
ECX = 262144; // 1 MB / 4
|
||||
asm {
|
||||
CLD
|
||||
REP STOSD
|
||||
}
|
||||
for (i=2; i*i<1000000; i++) {
|
||||
if (DSBYTE[buf+i]==0) {
|
||||
j = i*i;
|
||||
while (j<1000000) { DSBYTE[buf+j]=1; j += i; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dword hash1mb(dword buf)
|
||||
{
|
||||
dword i, h;
|
||||
h = 2166136261;
|
||||
for (i=0; i<1048576; i++) {
|
||||
h = h ^ DSBYTE[buf+i];
|
||||
h = h * 16777619;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
// build one random cycle of byte-offsets over buf (Sattolo shuffle):
|
||||
// following p = [buf+p] visits every node in random order - defeats
|
||||
// both the prefetcher and the cache -> pure dependent-load latency.
|
||||
void lat_build(dword buf)
|
||||
{
|
||||
dword i, j, t, ai, aj;
|
||||
for (i=0; i<LAT_N; i++) { ai = i*4; ESDWORD[buf+ai] = ai; }
|
||||
lat_rnd = 0x1A2B3C4D; // fixed seed: same chain on every machine
|
||||
i = LAT_N;
|
||||
while (i > 1) {
|
||||
i = i - 1;
|
||||
lat_rnd = lat_rnd * 1103515245; lat_rnd = lat_rnd + 12345;
|
||||
j = lat_rnd >> 8; j = j % i;
|
||||
ai = i*4; ai = ai + buf;
|
||||
aj = j*4; aj = aj + buf;
|
||||
t = ESDWORD[ai]; ESDWORD[ai] = ESDWORD[aj]; ESDWORD[aj] = t;
|
||||
}
|
||||
}
|
||||
|
||||
//--- Integer: 4 independent ALU chains, ~1e6 ops per unit ---
|
||||
// Interleaved so superscalar CPUs (P5+) can overlap them; a strictly
|
||||
// serial chain would only measure latency and hide pipelining.
|
||||
dword t_cpu_int()
|
||||
{
|
||||
dword c=0, i, x1, x2, x3, x4;
|
||||
BenchBegin();
|
||||
do {
|
||||
x1 = 0x12345678; x2 = 0x9E3779B9; x3 = 0x01234567; x4 = 0xABCDEF01;
|
||||
for (i=0; i<50000; i++) {
|
||||
x1 = x1 + i; x2 = x2 + i; x3 = x3 + i; x4 = x4 + i;
|
||||
x1 = x1 ^ 0x55AA55AA; x2 = x2 ^ 0x33CC33CC; x3 = x3 ^ 0x0F0F0F0F; x4 = x4 ^ 0x5A5A5A5A;
|
||||
x1 = x1 * 3; x2 = x2 * 3; x3 = x3 * 3; x4 = x4 * 3;
|
||||
x1 = x1 - i; x2 = x2 - i; x3 = x3 - i; x4 = x4 - i;
|
||||
x1 = x1 + x1; x2 = x2 + x2; x3 = x3 + x3; x4 = x4 + x4;
|
||||
}
|
||||
cpu_sink = x1; cpu_sink = cpu_sink ^ x2;
|
||||
cpu_sink = cpu_sink ^ x3; cpu_sink = cpu_sink ^ x4;
|
||||
c++; // 50000 * 20 = 1e6 ops
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MOps/s
|
||||
}
|
||||
|
||||
//--- Floating point: 4 independent mul/add chains, ~1e6 flops per unit ---
|
||||
// No division: one fdiv (15-40+ cycles) would dominate the whole chain
|
||||
// and the test would just measure fdiv latency.
|
||||
dword t_cpu_float()
|
||||
{
|
||||
dword c=0, i;
|
||||
float a1, a2, a3, a4, b, k;
|
||||
BenchBegin();
|
||||
do {
|
||||
a1 = 1.0; a2 = 1.1; a3 = 1.2; a4 = 1.3;
|
||||
b = 1.0000151; k = 0.9999847;
|
||||
for (i=0; i<62500; i++) {
|
||||
a1 = a1 * b; a2 = a2 * b; a3 = a3 * b; a4 = a4 * b;
|
||||
a1 = a1 + k; a2 = a2 + k; a3 = a3 + k; a4 = a4 + k;
|
||||
a1 = a1 * k; a2 = a2 * k; a3 = a3 * k; a4 = a4 * k;
|
||||
a1 = a1 - k; a2 = a2 - k; a3 = a3 - k; a4 = a4 - k;
|
||||
}
|
||||
cpu_fsink = a1; cpu_fsink = cpu_fsink + a2;
|
||||
cpu_fsink = cpu_fsink + a3; cpu_fsink = cpu_fsink + a4;
|
||||
c++; // 62500 * 16 = 1e6 flops
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MFLOP/s
|
||||
}
|
||||
|
||||
//--- Memory bandwidth: 2 MB forward copy per unit ---
|
||||
dword t_cpu_mem()
|
||||
{
|
||||
dword c=0;
|
||||
BenchBegin();
|
||||
do { copy_fwd(buf_b, buf_a, CPY_BYTES); c += CPY_MB; } while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MB/s
|
||||
}
|
||||
|
||||
//--- Memory latency: serial pointer chase over 2 MB, 1e6 hops per unit ---
|
||||
dword t_cpu_latency()
|
||||
{
|
||||
dword c=0, k, p;
|
||||
lat_build(buf_b);
|
||||
BenchBegin();
|
||||
do {
|
||||
p = 0;
|
||||
for (k=0; k<250000; k++) {
|
||||
p = ESDWORD[buf_b+p];
|
||||
p = ESDWORD[buf_b+p];
|
||||
p = ESDWORD[buf_b+p];
|
||||
p = ESDWORD[buf_b+p];
|
||||
}
|
||||
cpu_sink = p;
|
||||
c++; // 250000 * 4 = 1e6 dependent loads
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // Macc/s (100/result = ns per access)
|
||||
}
|
||||
|
||||
//--- Prime sieve: 1e6 cells per unit ---
|
||||
dword t_cpu_sieve()
|
||||
{
|
||||
dword c=0;
|
||||
BenchBegin();
|
||||
do { sieve1m(buf_b); c++; } while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // Mcell/s
|
||||
}
|
||||
|
||||
//--- Hash throughput (FNV-1a): 1 MB per unit ---
|
||||
dword t_cpu_hash()
|
||||
{
|
||||
dword c=0;
|
||||
BenchBegin();
|
||||
do { cpu_sink = hash1mb(buf_a); c++; } while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MB/s
|
||||
}
|
||||
|
||||
void Register_CPU()
|
||||
{
|
||||
RegisterTest(SECT_CPU, "Integer", "MOps/s", REF_INT, #t_cpu_int);
|
||||
RegisterTest(SECT_CPU, "Floating Point", "MFLOP/s", REF_FLOAT, #t_cpu_float);
|
||||
RegisterTest(SECT_CPU, "Memory Copy", "MB/s", REF_MEM, #t_cpu_mem);
|
||||
RegisterTest(SECT_CPU, "Memory Latency", "Macc/s", REF_LAT, #t_cpu_latency);
|
||||
RegisterTest(SECT_CPU, "Prime Sieve", "Mcell/s", REF_SIEVE, #t_cpu_sieve);
|
||||
RegisterTest(SECT_CPU, "Hash FNV-1a", "MB/s", REF_HASH, #t_cpu_hash);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,311 +0,0 @@
|
||||
#ifndef INCLUDE_TESTS_DISK_H
|
||||
#define INCLUDE_TESTS_DISK_H
|
||||
//========================================================//
|
||||
// Disk test module. //
|
||||
// Writes/reads a temp file via system fn 70. //
|
||||
// Target directory = disk_dir (set from the UI disk //
|
||||
// selector); falls back to the RAM disk /tmp0/1. //
|
||||
// NB: sequential rewrite of one file mostly measures the //
|
||||
// FS/cache throughput, not raw platter speed. //
|
||||
//========================================================//
|
||||
|
||||
#define REF_DWRITE 5000 // 50.00 MB/s
|
||||
#define REF_DREAD 5000
|
||||
#define REF_RWRITE 1000 // 10.00 MB/s (random 4K is much slower)
|
||||
#define REF_RREAD 1000
|
||||
#define REF_FS 50000 // 500.00 op/s (create/delete metadata ops)
|
||||
#define FS_N 10 // files + folders created per unit
|
||||
#define DISK_CHUNK CPY_BYTES // 2 MB per op (reuses buf_a - content irrelevant)
|
||||
#define DISK_MB 2
|
||||
#define RND_FILE 8388608 // 8 MB test file for random ops
|
||||
#define RND_BLK 4096 // 4 KB random block
|
||||
#define RND_NBLK 2048 // RND_FILE / RND_BLK
|
||||
|
||||
dword buf_disk = 0;
|
||||
dword disk_dir = 0; // -> selected target dir (set by the UI)
|
||||
dword rnd_state; // LCG state for random offsets
|
||||
char dk_op[32];
|
||||
char dk_file[80];
|
||||
|
||||
dword FileWrite(dword name, data, size)
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 2; // subfn 2 = create/rewrite
|
||||
ESDWORD[#dk_op+4] = 0;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = size;
|
||||
ESDWORD[#dk_op+16] = data;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX; // 0 = ok
|
||||
}
|
||||
|
||||
dword FileRead(dword name, data, size)
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 0; // subfn 0 = read
|
||||
ESDWORD[#dk_op+4] = 0;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = size;
|
||||
ESDWORD[#dk_op+16] = data;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX;
|
||||
}
|
||||
|
||||
dword dk_delete(dword name)
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 8; // subfn 8 = delete
|
||||
ESDWORD[#dk_op+4] = 0;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = 0;
|
||||
ESDWORD[#dk_op+16] = 0;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX;
|
||||
}
|
||||
|
||||
dword dk_mkdir(dword name)
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 9; // subfn 9 = create folder
|
||||
ESDWORD[#dk_op+4] = 0;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = 0;
|
||||
ESDWORD[#dk_op+16] = 0;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX;
|
||||
}
|
||||
|
||||
dword FileWriteAt(dword name, data, size, pos) // fn70.3 = write at position
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 3;
|
||||
ESDWORD[#dk_op+4] = pos;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = size;
|
||||
ESDWORD[#dk_op+16] = data;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX;
|
||||
}
|
||||
|
||||
dword FileReadAt(dword name, data, size, pos) // fn70.0 = read at position
|
||||
{
|
||||
ESDWORD[#dk_op+0] = 0;
|
||||
ESDWORD[#dk_op+4] = pos;
|
||||
ESDWORD[#dk_op+8] = 0;
|
||||
ESDWORD[#dk_op+12] = size;
|
||||
ESDWORD[#dk_op+16] = data;
|
||||
DSBYTE [#dk_op+20] = 0;
|
||||
ESDWORD[#dk_op+21] = name;
|
||||
EAX = 70;
|
||||
EBX = #dk_op;
|
||||
$int 0x40;
|
||||
return EAX;
|
||||
}
|
||||
|
||||
void DiskPath() // dk_file = <disk_dir>/bbtst.tmp
|
||||
{
|
||||
if (disk_dir) strcpy(#dk_file, disk_dir);
|
||||
else strcpy(#dk_file, "/tmp0/1");
|
||||
strcat(#dk_file, "/bbtst.tmp");
|
||||
}
|
||||
|
||||
// create/fill an 8 MB file so random 4K offsets are valid and physically written
|
||||
void EnsureRandFile()
|
||||
{
|
||||
dword pos;
|
||||
FileWrite(#dk_file, buf_disk, DISK_CHUNK); // create
|
||||
pos = DISK_CHUNK;
|
||||
while (pos < RND_FILE) {
|
||||
FileWriteAt(#dk_file, buf_disk, DISK_CHUNK, pos);
|
||||
pos += DISK_CHUNK;
|
||||
}
|
||||
}
|
||||
|
||||
// remove the temp file (called by the UI when a run finishes)
|
||||
void Disk_Cleanup()
|
||||
{
|
||||
DiskPath();
|
||||
dk_delete(#dk_file);
|
||||
}
|
||||
|
||||
dword t_disk_write()
|
||||
{
|
||||
dword c=0, r;
|
||||
if (!buf_disk) buf_disk = buf_a;
|
||||
DiskPath();
|
||||
BenchBegin();
|
||||
do {
|
||||
r = FileWrite(#dk_file, buf_disk, DISK_CHUNK);
|
||||
if (r) return BB_SKIP; // write error: no result, not a slow one
|
||||
c += DISK_MB;
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MB/s
|
||||
}
|
||||
|
||||
dword t_disk_read()
|
||||
{
|
||||
dword c=0, r;
|
||||
if (!buf_disk) buf_disk = buf_a;
|
||||
DiskPath();
|
||||
// Seq Write may be unticked - create the test file if it is missing
|
||||
r = FileRead(#dk_file, buf_disk, RND_BLK);
|
||||
if (r!=0) && (r!=6) FileWrite(#dk_file, buf_disk, DISK_CHUNK);
|
||||
BenchBegin();
|
||||
do {
|
||||
r = FileRead(#dk_file, buf_disk, DISK_CHUNK);
|
||||
if (r!=0) && (r!=6) return BB_SKIP; // 6 = EOF (still ok)
|
||||
c += DISK_MB;
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // MB/s
|
||||
}
|
||||
|
||||
// random 4K write at random offsets in the 8 MB file
|
||||
dword t_disk_rwrite()
|
||||
{
|
||||
dword c=0, pos, r;
|
||||
if (!buf_disk) buf_disk = buf_a;
|
||||
DiskPath();
|
||||
EnsureRandFile();
|
||||
rnd_state = 0x12345678; // fixed seed: same offsets on every run
|
||||
BenchBegin();
|
||||
do {
|
||||
rnd_state = rnd_state * 1103515245; rnd_state = rnd_state + 12345;
|
||||
r = rnd_state >> 8; r = r % RND_NBLK;
|
||||
pos = r * RND_BLK;
|
||||
if (FileWriteAt(#dk_file, buf_disk, RND_BLK, pos)) return BB_SKIP;
|
||||
c++;
|
||||
} while (BenchTicks() < 100);
|
||||
r = muldiv(c, 40000, BenchTicks()); // KiB/s x100 (c * 4 KiB)
|
||||
return r / 1024; // -> MB/s x100 (MiB, same as Seq)
|
||||
}
|
||||
|
||||
// random 4K read at random offsets (NB: hits the FS cache - can't be dropped)
|
||||
dword t_disk_rread()
|
||||
{
|
||||
dword c=0, pos, r, res;
|
||||
if (!buf_disk) buf_disk = buf_a;
|
||||
DiskPath();
|
||||
EnsureRandFile();
|
||||
rnd_state = 0x12345678; // fixed seed: same offsets on every run
|
||||
BenchBegin();
|
||||
do {
|
||||
rnd_state = rnd_state * 1103515245; rnd_state = rnd_state + 12345;
|
||||
r = rnd_state >> 8; r = r % RND_NBLK;
|
||||
pos = r * RND_BLK;
|
||||
res = FileReadAt(#dk_file, buf_disk, RND_BLK, pos);
|
||||
if (res!=0) && (res!=6) return BB_SKIP;
|
||||
c++;
|
||||
} while (BenchTicks() < 100);
|
||||
r = muldiv(c, 40000, BenchTicks()); // KiB/s x100 (c * 4 KiB)
|
||||
return r / 1024; // -> MB/s x100 (MiB, same as Seq)
|
||||
}
|
||||
|
||||
//---- File system: create/delete files and folders (metadata ops) ----
|
||||
char fs_fn[FS_N*64]; // pre-built file names (no sprintf in the loop)
|
||||
char fs_dn[FS_N*64]; // pre-built folder names
|
||||
|
||||
// names via strcpy/strcat only - the same primitives DiskWritable/DiskPath
|
||||
// use successfully on every disk (no sprintf/itoa in the path building).
|
||||
// No trailing slash anywhere: folder path is "<dir>/bbd_0".
|
||||
void fs_names_build()
|
||||
{
|
||||
dword i, p, dir;
|
||||
char dig[2];
|
||||
dir = disk_dir;
|
||||
if (!dir) dir = "/tmp0/1";
|
||||
dig[1] = 0;
|
||||
for (i=0; i<FS_N; i++) {
|
||||
dig[0] = i + '0';
|
||||
p = i*64; p = p + #fs_fn;
|
||||
strcpy(p, dir); strcat(p, "/bbf_"); strcat(p, #dig); strcat(p, ".tmp");
|
||||
p = i*64; p = p + #fs_dn;
|
||||
strcpy(p, dir); strcat(p, "/bbd_"); strcat(p, #dig);
|
||||
}
|
||||
}
|
||||
|
||||
void fs_wipe() // best-effort removal (also leftovers of a crash)
|
||||
{
|
||||
dword i, p;
|
||||
for (i=0; i<FS_N; i++) {
|
||||
p = i*64; p = p + #fs_fn; dk_delete(p);
|
||||
p = i*64; p = p + #fs_dn; dk_delete(p);
|
||||
}
|
||||
}
|
||||
|
||||
// one unit = create FS_N files (512 B) + FS_N folders, then delete them all.
|
||||
// BOTH phases are probed before timing and degrade independently: not every
|
||||
// writable FS driver implements every fn70 op (e.g. exFAT has no
|
||||
// CreateFolder at all). 0 only when neither files nor folders work.
|
||||
dword t_disk_fs()
|
||||
{
|
||||
dword c=0, i, p, r;
|
||||
byte files_ok, dirs_ok, ok;
|
||||
if (!buf_disk) buf_disk = buf_a;
|
||||
fs_names_build();
|
||||
fs_wipe();
|
||||
files_ok = 0; // probe file create+delete
|
||||
r = FileWrite(#fs_fn, buf_disk, 512);
|
||||
if (r==0) {
|
||||
r = dk_delete(#fs_fn);
|
||||
if (r==0) files_ok = 1;
|
||||
}
|
||||
dirs_ok = 0; // probe folder create+delete
|
||||
r = dk_mkdir(#fs_dn);
|
||||
if (r==0) {
|
||||
r = dk_delete(#fs_dn);
|
||||
if (r==0) dirs_ok = 1;
|
||||
}
|
||||
if (!files_ok) && (!dirs_ok) return BB_SKIP;
|
||||
BenchBegin();
|
||||
do {
|
||||
if (files_ok) {
|
||||
ok = 1;
|
||||
for (i=0; i<FS_N; i++) {
|
||||
p = i*64; p = p + #fs_fn;
|
||||
if (FileWrite(p, buf_disk, 512)) ok = 0;
|
||||
}
|
||||
for (i=0; i<FS_N; i++) { p = i*64; p = p + #fs_fn; dk_delete(p); }
|
||||
if (ok) c += 20; // 2 * FS_N file operations
|
||||
else files_ok = 0; // driver refused mid-run - stop trying
|
||||
}
|
||||
if (dirs_ok) {
|
||||
ok = 1;
|
||||
for (i=0; i<FS_N; i++) {
|
||||
p = i*64; p = p + #fs_dn;
|
||||
if (dk_mkdir(p)) ok = 0;
|
||||
}
|
||||
for (i=0; i<FS_N; i++) { p = i*64; p = p + #fs_dn; dk_delete(p); }
|
||||
if (ok) c += 20; // 2 * FS_N folder operations
|
||||
else dirs_ok = 0;
|
||||
}
|
||||
if (!files_ok) && (!dirs_ok) break;
|
||||
} while (BenchTicks() < 100);
|
||||
fs_wipe(); // belt and braces: no leftovers
|
||||
return PerSecX100(c); // op/s
|
||||
}
|
||||
|
||||
void Register_DISK()
|
||||
{
|
||||
RegisterTest(SECT_DISK, "Seq Write", "MB/s", REF_DWRITE, #t_disk_write);
|
||||
RegisterTest(SECT_DISK, "Seq Read", "MB/s", REF_DREAD, #t_disk_read);
|
||||
RegisterTest(SECT_DISK, "Rand Write", "MB/s", REF_RWRITE, #t_disk_rwrite);
|
||||
RegisterTest(SECT_DISK, "Rand Read", "MB/s", REF_RREAD, #t_disk_rread);
|
||||
RegisterTest(SECT_DISK, "File System", "op/s", REF_FS, #t_disk_fs);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,204 +0,0 @@
|
||||
#ifndef INCLUDE_TESTS_GPU_H
|
||||
#define INCLUDE_TESTS_GPU_H
|
||||
//========================================================//
|
||||
// Graphics (2D) test module. //
|
||||
// Tests draw into the window canvas (GCV_* region). //
|
||||
//========================================================//
|
||||
|
||||
#define REF_FILL 20000 // 200.00 MPix/s
|
||||
#define REF_BLIT 10000 // 100.00 MPix/s
|
||||
#define REF_READ 5000 // 50.00 MPix/s (VRAM read is slow)
|
||||
#define REF_VWRITE 100000 // 1000.00 MB/s (direct LFB write, WC-dependent)
|
||||
#define REF_LINE 50000 // 500.00 Kline/s
|
||||
#define REF_TEXT 30000 // 300.00 Kchar/s
|
||||
|
||||
char gpu_text_str[] = "BirdBench benchmark 0123456789ab";
|
||||
|
||||
void DrawLine38(dword x1,y1,x2,y2,color)
|
||||
{
|
||||
EAX = 38;
|
||||
EBX = x1<<16+x2;
|
||||
ECX = y1<<16+y2;
|
||||
EDX = color;
|
||||
$int 0x40;
|
||||
}
|
||||
|
||||
//--- Fill rate: solid bars (fn 13) ---
|
||||
dword t_gpu_fill()
|
||||
{
|
||||
dword c=0, col=0, mp;
|
||||
BenchBegin();
|
||||
do {
|
||||
DrawBar(GCV_X, GCV_Y, GCV_W, GCV_H, col);
|
||||
col += 0x0A0C0E;
|
||||
col = col & 0xFFFFFF; // bit 31 = gradient-fill flag (fn13 0x80RRGGBB)!
|
||||
c++;
|
||||
} while (BenchTicks() < 100);
|
||||
mp = muldiv(c, GCV_W*GCV_H, 1000000); // total mega-pixels
|
||||
return PerSecX100(mp); // MPix/s
|
||||
}
|
||||
|
||||
//--- Blit rate: 24bpp image (fn 7) ---
|
||||
dword t_gpu_blit()
|
||||
{
|
||||
dword c=0, mp;
|
||||
BenchBegin();
|
||||
do { PutImage(GCV_X, GCV_Y, GCV_W, GCV_H, buf_canvas); c++; }
|
||||
while (BenchTicks() < 100);
|
||||
mp = muldiv(c, GCV_W*GCV_H, 1000000);
|
||||
return PerSecX100(mp); // MPix/s
|
||||
}
|
||||
|
||||
//--- Line rate: 1000 lines (fn 38) per unit ---
|
||||
dword t_gpu_lines()
|
||||
{
|
||||
dword c=0, i, col=0x3388CC;
|
||||
dword x1,y1,x2,y2;
|
||||
BenchBegin();
|
||||
do {
|
||||
for (i=0; i<1000; i++) {
|
||||
x1 = i*7; x1 = x1 % GCV_W; x1 = x1 + GCV_X;
|
||||
y1 = i*13; y1 = y1 % GCV_H; y1 = y1 + GCV_Y;
|
||||
x2 = i*29; x2 = x2 % GCV_W; x2 = x2 + GCV_X;
|
||||
y2 = i*23; y2 = y2 % GCV_H; y2 = y2 + GCV_Y;
|
||||
DrawLine38(x1,y1,x2,y2,col);
|
||||
col += 0x0A1420;
|
||||
col = col & 0xFFFFFF; // bit 24 = inversed-line flag (fn38 0x01xxxxxx)!
|
||||
}
|
||||
c++; // 1000 lines = 1 Kline
|
||||
} while (BenchTicks() < 100);
|
||||
return PerSecX100(c); // Kline/s
|
||||
}
|
||||
|
||||
//--- Text rate: WriteText (fn 4), both kernel fonts (6x9 + 8x16) ---
|
||||
// Subpixel smoothing is forced for the duration (the heaviest glyph
|
||||
// path), then the user's setting is restored.
|
||||
dword t_gpu_text()
|
||||
{
|
||||
dword c=0, i, y, len, kc, sm;
|
||||
len = strlen(#gpu_text_str);
|
||||
EAX = 48; EBX = 9; $int 0x40; // SSF_GET_FONT_SMOOTH
|
||||
sm = EAX;
|
||||
EAX = 48; EBX = 10; ECX = 2; $int 0x40; // SSF_SET_FONT_SMOOTH: subpixel
|
||||
BenchBegin();
|
||||
do {
|
||||
for (i=0; i<25; i++) {
|
||||
y = i*11; y = y % GCV_H; y = y + GCV_Y;
|
||||
WriteText(GCV_X, y, 0x80, 0x101010, #gpu_text_str); // 6x9
|
||||
}
|
||||
for (i=0; i<25; i++) {
|
||||
y = i*17; y = y % GCV_H; y = y + GCV_Y;
|
||||
WriteText(GCV_X, y, 0x90, 0x101010, #gpu_text_str); // 8x16
|
||||
}
|
||||
c++; // 50 * len chars
|
||||
} while (BenchTicks() < 100);
|
||||
EAX = 48; EBX = 10; ECX = sm; $int 0x40; // restore user's smoothing
|
||||
kc = muldiv(c, 50*len, 1000); // total kilo-chars
|
||||
return PerSecX100(kc); // Kchar/s
|
||||
}
|
||||
|
||||
//--- VRAM read-back: read screen area to RAM (fn 36) ---
|
||||
dword t_gpu_read()
|
||||
{
|
||||
dword c=0, mp, sx, sy;
|
||||
proc_info p;
|
||||
GetProcessInfo(#p, SelfInfo); // fn 36 uses absolute screen coords
|
||||
sx = p.left; sx = sx + 5; sx = sx + GCV_X;
|
||||
sy = p.top; sy = sy + skin_h; sy = sy + GCV_Y;
|
||||
BenchBegin();
|
||||
do {
|
||||
CopyScreen(buf_canvas, sx, sy, GCV_W, GCV_H); // 24bpp -> buf
|
||||
c++;
|
||||
} while (BenchTicks() < 100);
|
||||
mp = muldiv(c, GCV_W*GCV_H, 1000000);
|
||||
return PerSecX100(mp); // MPix/s
|
||||
}
|
||||
|
||||
//--- direct VRAM write: rep stosd into the LFB via the GS selector ---
|
||||
// The kernel gives apps a writable GS whose base = LFBAddress (see kernel.asm:
|
||||
// "Set base of graphic segment to linear address of LFB"). rep stosd needs
|
||||
// ES:EDI, so we copy GS into ES for the duration, then restore it. No window
|
||||
// clipping here - we fill only our own on-screen rectangle, scanline by scanline.
|
||||
// GS segment limit via LSL (unprivileged). If the video mode has no LFB
|
||||
// (banked VGA), the selector window is tiny and writing past it would #GP.
|
||||
dword gs_limit()
|
||||
{
|
||||
asm {
|
||||
XOR EAX, EAX
|
||||
MOV AX, GS
|
||||
LSL EAX, EAX
|
||||
}
|
||||
}
|
||||
|
||||
inline fastcall vram_fill_gs(EDI, ESI, EDX, ECX) // ofs, dwords/row, row-advance, rows
|
||||
{
|
||||
asm {
|
||||
push es
|
||||
push ebx
|
||||
mov ebx, ecx // ebx = row count
|
||||
mov ax, gs
|
||||
mov es, ax // es -> LFB
|
||||
cld
|
||||
kvw1:
|
||||
mov ecx, esi // dwords per scanline
|
||||
mov eax, 0x00336699 // fill pattern
|
||||
rep stosd
|
||||
add edi, edx // -> next scanline
|
||||
dec ebx
|
||||
jnz kvw1
|
||||
pop ebx
|
||||
pop es
|
||||
}
|
||||
}
|
||||
|
||||
dword t_gpu_vramwrite()
|
||||
{
|
||||
dword c=0, sx, sy, cols, rows, pitch, bpp, bpp_b, off, rowbytes, rowdw, rowadv, bpf, mb, t, lim;
|
||||
proc_info p;
|
||||
GetProcessInfo(#p, SelfInfo);
|
||||
EAX = 61; EBX = 3; $int 0x40; pitch = EAX; // bytes per scanline
|
||||
EAX = 61; EBX = 2; $int 0x40; bpp = EAX; // bits per pixel
|
||||
bpp_b = bpp + 7; bpp_b = bpp_b / 8;
|
||||
if (bpp_b < 1) bpp_b = 4;
|
||||
sx = p.left; sx = sx + 5; sx = sx + GCV_X;
|
||||
sy = p.top; sy = sy + skin_h; sy = sy + GCV_Y;
|
||||
// clamp to the screen - writing past the LFB would #GP (small screens!)
|
||||
if (sx >= screen.w) return BB_SKIP;
|
||||
if (sy >= screen.h) return BB_SKIP;
|
||||
cols = GCV_W; t = sx + cols; if (t > screen.w) cols = screen.w - sx;
|
||||
rows = GCV_H; t = sy + rows; if (t > screen.h) rows = screen.h - sy;
|
||||
rowbytes = cols * bpp_b;
|
||||
if (pitch < rowbytes) pitch = rowbytes;
|
||||
// stosd moves whole dwords: trim the row to a multiple of 4 so rowadv and
|
||||
// the reported byte count match what was actually written (at 24/16 bpp
|
||||
// rowbytes is not divisible by 4 and every row would drift by 1-2 bytes)
|
||||
rowdw = rowbytes / 4;
|
||||
rowbytes = rowdw * 4;
|
||||
rowadv = pitch - rowbytes;
|
||||
t = sx * bpp_b;
|
||||
off = sy * pitch; off = off + t;
|
||||
// last byte we will touch must be inside the GS segment (no-LFB safety)
|
||||
t = rows - 1; t = t * pitch; t = t + off; t = t + rowbytes; t = t - 1;
|
||||
lim = gs_limit();
|
||||
if (t > lim) return BB_SKIP;
|
||||
BenchBegin();
|
||||
do {
|
||||
vram_fill_gs(off, rowdw, rowadv, rows);
|
||||
c++;
|
||||
} while (BenchTicks() < 100);
|
||||
bpf = rowbytes * rows; // bytes per frame
|
||||
mb = muldiv(c, bpf, 1048576); // total MB written (MiB, like the disk tests)
|
||||
return PerSecX100(mb); // MB/s
|
||||
}
|
||||
|
||||
void Register_GPU()
|
||||
{
|
||||
RegisterTest(SECT_GPU, "Fill Rate", "MPix/s", REF_FILL, #t_gpu_fill);
|
||||
RegisterTest(SECT_GPU, "Blit (f7)", "MPix/s", REF_BLIT, #t_gpu_blit);
|
||||
RegisterTest(SECT_GPU, "VRAM Read (f36)","MPix/s", REF_READ, #t_gpu_read);
|
||||
RegisterTest(SECT_GPU, "VRAM Write (gs)","MB/s", REF_VWRITE, #t_gpu_vramwrite);
|
||||
RegisterTest(SECT_GPU, "Lines (f38)", "Kline/s", REF_LINE, #t_gpu_lines);
|
||||
RegisterTest(SECT_GPU, "Text (f4)", "Kchar/s", REF_TEXT, #t_gpu_text);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,285 +0,0 @@
|
||||
#include "TWB\colors.h"
|
||||
#include "TWB\anchors.h"
|
||||
#include "TWB\parse_tag.h"
|
||||
#include "TWB\special.h"
|
||||
#include "TWB\tag_list.h"
|
||||
#define DEFAULT_BG_COL 0xffFBE5E4; //- peach; 0xffEBE8E9 - more grey
|
||||
dword link_color_default;
|
||||
dword link_color_active;
|
||||
#include "TWB\links.h"
|
||||
|
||||
#define BODY_MARGIN 6
|
||||
#define BASIC_CHAR_W 8
|
||||
#define BASIC_LINE_H 18
|
||||
|
||||
struct STYLE {
|
||||
bool
|
||||
b, u, s, h,
|
||||
font,
|
||||
pre,
|
||||
blq,
|
||||
button,
|
||||
image,
|
||||
nav, header;
|
||||
LIST tag_list;
|
||||
dword title;
|
||||
dword cur_line_h;
|
||||
void reset();
|
||||
};
|
||||
|
||||
void STYLE::reset()
|
||||
{
|
||||
b = u = s = h = font = pre = blq =
|
||||
title = button = image = nav = header = false;
|
||||
cur_line_h = NULL;
|
||||
tag_list.reset();
|
||||
}
|
||||
|
||||
struct TWebBrowser {
|
||||
llist list;
|
||||
STYLE style;
|
||||
dword draw_y, draw_x, draw_w, left_gap;
|
||||
dword o_bufpointer;
|
||||
int cur_encoding, custom_encoding;
|
||||
bool link, t_html, t_body;
|
||||
dword bufpointer;
|
||||
dword bufsize;
|
||||
dword is_html;
|
||||
collection img_url;
|
||||
char header[150];
|
||||
char linebuf[500];
|
||||
char redirect[URL_SIZE];
|
||||
|
||||
bool secondrun;
|
||||
|
||||
void SetStyle();
|
||||
void RenderTextbuf();
|
||||
void RenderLine();
|
||||
bool RenderImage();
|
||||
|
||||
void SetPageDefaults();
|
||||
void ParseHtml();
|
||||
void Reparse();
|
||||
void NewLine();
|
||||
void ChangeEncoding();
|
||||
void AddCharToTheLine();
|
||||
void DrawPage();
|
||||
|
||||
void tag_a();
|
||||
void tag_p();
|
||||
void tag_img();
|
||||
void tag_kosicon();
|
||||
void tag_div();
|
||||
void tag_h1234_caption();
|
||||
void tag_ol_ul_dt();
|
||||
void tag_li();
|
||||
void tag_q();
|
||||
void tag_hr();
|
||||
void tag_code();
|
||||
void tag_meta_xml();
|
||||
void tag_body();
|
||||
void tag_iframe();
|
||||
void tag_title();
|
||||
void tag_font();
|
||||
void tag_table_reset();
|
||||
void tag_table();
|
||||
void tag_td();
|
||||
void tag_tr();
|
||||
void reset_font_style();
|
||||
};
|
||||
|
||||
#include "TWB\render.h"
|
||||
#include "TWB\set_style.h"
|
||||
//============================================================================================
|
||||
void TWebBrowser::SetPageDefaults()
|
||||
{
|
||||
t_html = t_body = link = false;
|
||||
style.reset();
|
||||
reset_font_style();
|
||||
link_color_default = 0x0000FF;
|
||||
link_color_active = 0xFF0000;
|
||||
links.clear();
|
||||
anchors.clear();
|
||||
img_url.drop();
|
||||
text_colors.drop();
|
||||
text_colors.add(0);
|
||||
if (secondrun) {
|
||||
canvas.Init(list.x, list.y, list.w, math.max(list.visible, list.count)+200);
|
||||
canvas.Fill(0, bg_colors.get(0));
|
||||
}
|
||||
bg_colors.drop();
|
||||
bg_colors.add(DEFAULT_BG_COL);
|
||||
header = NULL;
|
||||
draw_y = BODY_MARGIN;
|
||||
draw_x = left_gap = BODY_MARGIN;
|
||||
draw_w = list.w - BODY_MARGIN - BODY_MARGIN;
|
||||
linebuf = 0;
|
||||
redirect = '\0';
|
||||
tag_table_reset();
|
||||
is_html = true;
|
||||
if (!strstri(bufpointer, "<body")) {
|
||||
t_body = true;
|
||||
if (!strstri(bufpointer, "<html")) && (!strstri(bufpointer, "<head")) && (!strstri(bufpointer, "<title"))
|
||||
&& (!strstr(bufpointer, "<?xml")) && (!strstr(bufpointer, "<xml")) {
|
||||
style.pre = true; //show linebreaks for a plaint text
|
||||
is_html = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//============================================================================================
|
||||
void TWebBrowser::Reparse()
|
||||
{
|
||||
ParseHtml(bufpointer, bufsize);
|
||||
}
|
||||
//============================================================================================
|
||||
void TWebBrowser::ParseHtml(dword _bufpointer, _bufsize){
|
||||
int tab_len;
|
||||
dword bufpos;
|
||||
bufsize = _bufsize;
|
||||
|
||||
if (bufpointer == _bufpointer) {
|
||||
custom_encoding = cur_encoding;
|
||||
} else {
|
||||
bufpointer = malloc(bufsize);
|
||||
memmov(bufpointer, _bufpointer, bufsize);
|
||||
|
||||
//hold original buffer
|
||||
o_bufpointer = malloc(bufsize);
|
||||
memmov(o_bufpointer, bufpointer, bufsize);
|
||||
|
||||
cur_encoding = CH_CP866;
|
||||
if (custom_encoding != -1) {
|
||||
cur_encoding = custom_encoding;
|
||||
bufpointer = ChangeCharset(cur_encoding, CH_CP866, bufpointer);
|
||||
bufsize = strlen(bufpointer);
|
||||
}
|
||||
}
|
||||
|
||||
table.cols.drop();
|
||||
secondrun = false;
|
||||
|
||||
_PARSE_START_:
|
||||
|
||||
SetPageDefaults();
|
||||
for (bufpos=bufpointer; bufpos < bufpointer+bufsize; bufpos++;)
|
||||
{
|
||||
if (style.pre) {
|
||||
if (ESBYTE[bufpos] == 0x0a) {
|
||||
RenderTextbuf();
|
||||
NewLine();
|
||||
continue;
|
||||
}
|
||||
if (ESBYTE[bufpos] == 0x09) {
|
||||
tab_len = draw_x - left_gap / list.font_w + strlen(#linebuf) % 4;
|
||||
if (!tab_len) tab_len = 4; else tab_len = 4 - tab_len;
|
||||
while (tab_len) {chrcat(#linebuf,' '); tab_len--;}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ESBYTE[bufpos] == '&') {
|
||||
bufpos = GetUnicodeSymbol(#linebuf, sizeof(TWebBrowser.linebuf)-1, bufpos+1, bufpointer+bufsize);
|
||||
continue;
|
||||
}
|
||||
if (ESBYTE[bufpos] == '<') && (is_html) {
|
||||
if (strchr("!/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", ESBYTE[bufpos+1])) {
|
||||
bufpos++;
|
||||
if (tag.parse(#bufpos, bufpointer + bufsize)) {
|
||||
|
||||
/*
|
||||
if (secondrun)
|
||||
{
|
||||
if (streq(#tag.name, "tr")) debugln(" ");
|
||||
if (!tag.opened) {
|
||||
debugch('/');
|
||||
} else {
|
||||
debugch(' ');
|
||||
}
|
||||
debugln(sprintf(#param, "%s x%i y%i %s",
|
||||
#tag.name, draw_x, draw_y, #linebuf));
|
||||
}
|
||||
//*/
|
||||
RenderTextbuf();
|
||||
if (debug_mode) { debugch('<'); if(!tag.opened)debugch('/'); debug(#tag.name); debugln(">"); }
|
||||
$push cur_encoding
|
||||
SetStyle();
|
||||
$pop eax
|
||||
// The thing is that UTF if longer than other encodings.
|
||||
// So if encoding was changed from UTF to DOS than $bufpos position got wrong,
|
||||
// and we have to start parse from the very beginning
|
||||
if (EAX != cur_encoding) && (cur_encoding == CH_UTF8) {
|
||||
ParseHtml(bufpointer, strlen(bufpointer));
|
||||
return;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
AddCharToTheLine(ESBYTE[bufpos]);
|
||||
}
|
||||
|
||||
RenderTextbuf();
|
||||
list.count = draw_y + style.cur_line_h;
|
||||
list.CheckDoesValuesOkey();
|
||||
anchors.current = NULL;
|
||||
|
||||
if (!secondrun) {
|
||||
secondrun = true;
|
||||
goto _PARSE_START_;
|
||||
}
|
||||
if (!header) {
|
||||
strncpy(#header, #version, sizeof(TWebBrowser.header)-1);
|
||||
DrawTitle(#header);
|
||||
}
|
||||
}
|
||||
//============================================================================================
|
||||
void TWebBrowser::AddCharToTheLine(unsigned char _char)
|
||||
{
|
||||
dword line_len = strlen(#linebuf);
|
||||
if (_char<=15) _char=' ';
|
||||
if (!style.pre) && (_char == ' ')
|
||||
{
|
||||
if (linebuf[line_len-1]==' ') return; //no double spaces
|
||||
if (draw_x==left_gap) && (!linebuf) return; //no paces at the beginning of the line
|
||||
if (link) && (line_len==0) return;
|
||||
}
|
||||
if (line_len < sizeof(TWebBrowser.linebuf)) {
|
||||
chrcat(#linebuf+line_len, _char);
|
||||
} else {
|
||||
RenderTextbuf();
|
||||
}
|
||||
}
|
||||
//============================================================================================
|
||||
void TWebBrowser::ChangeEncoding(int _new_encoding)
|
||||
{
|
||||
if (cur_encoding == _new_encoding) return;
|
||||
cur_encoding = _new_encoding;
|
||||
bufpointer = ChangeCharset(cur_encoding, CH_CP866, bufpointer);
|
||||
if (header) {
|
||||
ChangeCharset(cur_encoding, CH_CP866, #header);
|
||||
DrawTitle(#header);
|
||||
}
|
||||
}
|
||||
//============================================================================================
|
||||
scroll_bar scroll_wv = { 15,NULL,NULL,NULL,
|
||||
0,2,NULL,0,0,0xeeeeee,0xBBBbbb,0xeeeeee};
|
||||
|
||||
void TWebBrowser::DrawPage()
|
||||
{
|
||||
if (list.w!=canvas.bufw) Reparse();
|
||||
canvas.Show(list.first, list.h);
|
||||
|
||||
scroll_wv.max_area = list.count;
|
||||
scroll_wv.cur_area = list.visible;
|
||||
scroll_wv.position = list.first;
|
||||
scroll_wv.all_redraw = 0;
|
||||
scroll_wv.start_x = list.x + list.w;
|
||||
scroll_wv.start_y = list.y;
|
||||
scroll_wv.size_y = list.h;
|
||||
|
||||
if (list.count <= list.visible) {
|
||||
DrawBar(scroll_wv.start_x, scroll_wv.start_y, scroll_wv.size_x,
|
||||
scroll_wv.size_y, bg_colors.get(0) & 0x00FFFFFF);
|
||||
} else {
|
||||
scrollbar_v_draw(#scroll_wv);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
struct _anchors {
|
||||
char current[256];
|
||||
collection anchor_name;
|
||||
collection anchor_position;
|
||||
void add();
|
||||
int get_pos_by_name();
|
||||
void clear();
|
||||
void take_anchor_from();
|
||||
} anchors=0;
|
||||
|
||||
void _anchors::add(dword _name, _pos)
|
||||
{
|
||||
anchor_name.add(_name);
|
||||
anchor_position.add(itoa(_pos));
|
||||
}
|
||||
|
||||
int _anchors::get_pos_by_name(dword _get_name)
|
||||
{
|
||||
dword pos_name = anchor_name.get_pos_by_name(_get_name);
|
||||
if (ESBYTE[_get_name]==NULL) return 0;
|
||||
if (pos_name==-1) {
|
||||
return -1;
|
||||
} else {
|
||||
return atoi(anchor_position.get(pos_name));
|
||||
}
|
||||
}
|
||||
|
||||
void _anchors::clear()
|
||||
{
|
||||
anchor_name.drop();
|
||||
anchor_position.drop();
|
||||
}
|
||||
|
||||
void _anchors::take_anchor_from(dword _URL)
|
||||
{
|
||||
int anchor_pos;
|
||||
if (!current) && (_URL) && (anchor_pos = strrchr(_URL, '#')) {
|
||||
strncpy(#current, _URL+anchor_pos-1, sizeof(_anchors.current)-1);
|
||||
ESBYTE[_URL+anchor_pos-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
collection_int text_colors;
|
||||
collection_int bg_colors;
|
||||
|
||||
struct WEB_COLORS {
|
||||
char *name;
|
||||
dword rgb;
|
||||
} web_colors[] = {
|
||||
"aliceblue", 0xF0F8FF, "antiquewhite", 0xFAEBD7, "aqua", 0x00FFFF, "aquamarine", 0x7FFFD4,
|
||||
"azure", 0xF0FFFF, "beige", 0xF5F5DC, "bisque", 0xFFE4C4, "black", 0x000000,
|
||||
"blanchedalmond", 0xFFEBCD, "blue", 0x0000FF, "blueviolet", 0x8A2BE2, "brown", 0xA52A2A,
|
||||
"burlywood", 0xDEB887, "cadetblue", 0x5F9EA0, "chartreuse", 0x7FFF00, "chocolate", 0xD2691E,
|
||||
"coral", 0xFF7F50, "cornflowerblue", 0x6495ED, "cornsilk", 0xFFF8DC, "crimson", 0xDC143C,
|
||||
"cyan", 0x00FFFF, "darkblue", 0x00008B, "darkcyan", 0x008B8B, "darkgoldenrod", 0xB8860B,
|
||||
"darkgray", 0xA9A9A9, "darkgreen", 0x006400, "darkkhaki", 0xBDB76B, "darkmagenta", 0x8B008B,
|
||||
"darkolivegreen", 0x556B2F, "darkorange", 0xFF8C00, "darkorchid", 0x9932CC, "darkred", 0x8B0000,
|
||||
"darksalmon", 0xE9967A, "darkseagreen", 0x8FBC8F, "darkslateblue", 0x483D8B, "darkslategray", 0x2F4F4F,
|
||||
"darkturquoise", 0x00CED1, "darkviolet", 0x9400D3, "deeppink", 0xFF1493, "deepskyblue", 0x00BFFF,
|
||||
"dimgray", 0x696969, "dodgerblue", 0x1E90FF, "firebrick", 0xB22222, "floralwhite", 0xFFFAF0,
|
||||
"forestgreen", 0x228B22, "fuchsia", 0xFF00FF, "gainsboro", 0xDCDCDC, "ghostwhite", 0xF8F8FF,
|
||||
"gold", 0xFFD700, "goldenrod", 0xDAA520, "gray", 0x808080, "green", 0x008000,
|
||||
"greenyellow", 0xADFF2F, "honeydew", 0xF0FFF0, "hotpink", 0xFF69B4, "indianred", 0xCD5C5C,
|
||||
"indigo", 0x4B0082, "ivory", 0xFFFFF0, "khaki", 0xF0E68C, "lavender", 0xE6E6FA,
|
||||
"lavenderblush", 0xFFF0F5, "lawngreen", 0x7CFC00, "lemonchiffon", 0xFFFACD, "lightblue", 0xADD8E6,
|
||||
"lightcoral", 0xF08080, "lightcyan", 0xE0FFFF, "lightgreen", 0x90EE90, "lightgrey", 0xD3D3D3,
|
||||
"lightpink", 0xFFB6C1, "lightsalmon", 0xFFA07A, "lightseagreen", 0x20B2AA, "lightskyblue", 0x87CEFA,
|
||||
"lightslategray", 0x778899, "lightsteelblue", 0xB0C4DE, "lightyellow", 0xFFFFE0, "lime", 0x00FF00,
|
||||
"limegreen", 0x32CD32, "linen", 0xFAF0E6, "magenta", 0xFF00FF, "maroon", 0x800000,
|
||||
"mediumaquamarine", 0x66CDAA, "mediumblue", 0x0000CD, "mediumorchid", 0xBA55D3, "mediumpurple", 0x9370DB,
|
||||
"mediumseagreen", 0x3CB371, "mediumslateblue", 0x7B68EE, "mediumspringgreen",0x00FA9A, "mediumturquoise", 0x48D1CC,
|
||||
"mediumvioletred", 0xC71585, "midnightblue", 0x191970, "mintcream", 0xF5FFFA, "mistyrose", 0xFFE4E1,
|
||||
"moccasin", 0xFFE4B5, "navajowhite", 0xFFDEAD, "navy", 0x000080, "oldlace", 0xFDF5E6,
|
||||
"olive", 0x808000, "olivedrab", 0x6B8E23, "orange", 0xFFA500, "orangered", 0xFF4500,
|
||||
"orchid", 0xDA70D6, "palegoldenrod", 0xEEE8AA, "palegreen", 0x98FB98, "paleturquoise", 0xAFEEEE,
|
||||
"palevioletred", 0xDB7093, "papayawhip", 0xFFEFD5, "peachpuff", 0xFFDAB9, "peru", 0xCD853F,
|
||||
"pink", 0xFFC0CB, "plum", 0xDDA0DD, "powderblue", 0xB0E0E6, "purple", 0x800080,
|
||||
"red", 0xFF0000, "rosybrown", 0xBC8F8F, "royalblue", 0x4169E1, "saddlebrown", 0x8B4513,
|
||||
"salmon", 0xFA8072, "sandybrown", 0xF4A460, "seagreen", 0x2E8B57, "seashell", 0xFFF5EE,
|
||||
"sienna", 0xA0522D, "silver", 0xC0C0C0, "skyblue", 0x87CEEB, "slateblue", 0x6A5ACD,
|
||||
"slategray", 0x708090, "snow", 0xFFFAFA, "springgreen", 0x00FF7F, "steelblue", 0x4682B4,
|
||||
"tan", 0xD2B48C, "teal", 0x008080, "thistle", 0xD8BFD8, "tomato", 0xFF6347,
|
||||
"turquoise", 0x40E0D0, "violet", 0xEE82EE, "wheat", 0xF5DEB3, "white", 0xFFFFFF,
|
||||
"whitesmoke", 0xF5F5F5, "yellow", 0xFFFF00, "yellowgreen", 0x9ACD32, 0};
|
||||
|
||||
dword GetColor(char* color_str)
|
||||
{
|
||||
int ii;
|
||||
dword textlen=0;
|
||||
dword color=0;
|
||||
|
||||
strlwr(color_str);
|
||||
if (ESBYTE[color_str] == '#') {
|
||||
color_str++;
|
||||
} else {
|
||||
for (ii=0; web_colors[ii].name!=0; ii++)
|
||||
{
|
||||
if (streq(color_str, web_colors[ii].name)) return web_colors[ii].rgb;
|
||||
}
|
||||
}
|
||||
|
||||
textlen = strlen(color_str);
|
||||
if (textlen==6) || (textlen==3)
|
||||
{
|
||||
FOR (ii=0; ii<textlen; ii++)
|
||||
{
|
||||
BL = ESBYTE[color_str+ii];
|
||||
IF ((BL>='0') && (BL<='9')) BL -= '0';
|
||||
//IF ((BL>='A') && (BL<='F')) BL -= 'A'-10;
|
||||
IF ((BL>='a') && (BL<='f')) BL -= 'a'-10;
|
||||
color = color*0x10 + BL;
|
||||
if (textlen==3) color = color*0x10 + BL; //#abc ->> #aabbcc
|
||||
}
|
||||
return color;
|
||||
}
|
||||
return text_colors.get(0);
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
CustomCursor CursorPointer;
|
||||
dword CursorFile = FROM "TWB/pointer.cur";
|
||||
#include "..\lib\collection.h"
|
||||
|
||||
struct PAGE_LINKS {
|
||||
collection unic_links;
|
||||
collection element_links;
|
||||
|
||||
collection_int x;
|
||||
collection_int y;
|
||||
collection_int w;
|
||||
collection_int h;
|
||||
collection_int id;
|
||||
collection_int underline_h;
|
||||
|
||||
signed int active;
|
||||
dword active_url;
|
||||
bool hover();
|
||||
void add_link();
|
||||
void add_text();
|
||||
void clear();
|
||||
void draw_underline();
|
||||
} links;
|
||||
|
||||
void PAGE_LINKS::add_link(dword lpath)
|
||||
{
|
||||
unic_links.add(lpath);
|
||||
}
|
||||
|
||||
void PAGE_LINKS::add_text(dword _x, _y, _w, _h, _underline_h)
|
||||
{
|
||||
x.add(_x);
|
||||
y.add(_y);
|
||||
w.add(_w);
|
||||
h.add(_h);
|
||||
underline_h.add(_underline_h);
|
||||
element_links.add(unic_links.get_last());
|
||||
id.add(unic_links.count);
|
||||
}
|
||||
|
||||
void PAGE_LINKS::clear()
|
||||
{
|
||||
x.drop();
|
||||
y.drop();
|
||||
w.drop();
|
||||
h.drop();
|
||||
underline_h.drop();
|
||||
id.drop();
|
||||
|
||||
element_links.drop();
|
||||
unic_links.drop();
|
||||
|
||||
active = -1;
|
||||
active_url = 0;
|
||||
CursorPointer.Restore();
|
||||
}
|
||||
|
||||
void PAGE_LINKS::draw_underline(signed _id, dword list_first, list_y, color)
|
||||
{
|
||||
int i;
|
||||
if (_id == -1) return;
|
||||
for (i=0; i<id.count; i++)
|
||||
{
|
||||
if (id.get(i) - id.get(_id) == 0)
|
||||
&& (y.get(i) + h.get(i) - list_first > list_y) {
|
||||
DrawBar(x.get(i), y.get(i) + h.get(i) - list_first,
|
||||
w.get(i), underline_h.get(i), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PAGE_LINKS::hover(dword list_y, list_first)
|
||||
{
|
||||
int i;
|
||||
int mx = mouse.x;
|
||||
int my = mouse.y + list_first;
|
||||
if (!id.count) return false;
|
||||
|
||||
//Here we check is any link hovered
|
||||
for (i=0; i<id.count; i++)
|
||||
{
|
||||
if (mx>x.get(i)) && (my>y.get(i))
|
||||
&& (mx<x.get(i)+w.get(i)) && (my<y.get(i)+h.get(i))
|
||||
&& (my>list_y+list_first)
|
||||
{
|
||||
if (active!=i) {
|
||||
CursorPointer.Load(#CursorFile);
|
||||
CursorPointer.Set();
|
||||
|
||||
draw_underline(active, list_first, list_y, link_color_default);
|
||||
draw_underline(i, list_first, list_y, DEFAULT_BG_COL);
|
||||
|
||||
active_url = element_links.get(i);
|
||||
active = i;
|
||||
DrawStatusBar(active_url);
|
||||
}
|
||||
if (mouse.lkm) && (mouse.down) {
|
||||
DrawRectangle(x.get(active), -list_first + y.get(active),
|
||||
w.get(active), h.get(active), 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (active_url) {
|
||||
CursorPointer.Restore();
|
||||
draw_underline(active, list_first, list_y, link_color_default);
|
||||
active_url = 0;
|
||||
active = -1;
|
||||
DrawStatusBar(NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
struct _DOM {
|
||||
collection tag;
|
||||
collection tagparam;
|
||||
collection_int parent;
|
||||
} dom;
|
||||
*/
|
||||
|
||||
struct _tag
|
||||
{
|
||||
char name[32];
|
||||
char prior[32];
|
||||
bool opened;
|
||||
collection attributes;
|
||||
collection values;
|
||||
dword value;
|
||||
dword number;
|
||||
bool is();
|
||||
bool parse();
|
||||
dword get_next_param();
|
||||
dword get_value_of();
|
||||
signed get_number_of();
|
||||
} tag=0;
|
||||
|
||||
bool _tag::is(dword _text)
|
||||
{
|
||||
return streq(#name, _text);
|
||||
}
|
||||
|
||||
bool _tag::parse(dword _bufpos, bufend)
|
||||
{
|
||||
bool retok = true;
|
||||
dword bufpos = ESDWORD[_bufpos];
|
||||
dword params, paramsend;
|
||||
|
||||
dword closepos;
|
||||
dword whitepos;
|
||||
dword openpos;
|
||||
|
||||
if (name) strcpy(#prior, #name); else prior = '\0';
|
||||
name = '\0';
|
||||
attributes.drop();
|
||||
values.drop();
|
||||
|
||||
if (!strncmp(bufpos,"!--",3))
|
||||
{
|
||||
bufpos+=3;
|
||||
//STRSTR
|
||||
while (strncmp(bufpos,"-->",3)!=0) && (bufpos < bufend)
|
||||
{
|
||||
bufpos++;
|
||||
}
|
||||
bufpos+=2;
|
||||
retok = false;
|
||||
goto _RET;
|
||||
}
|
||||
|
||||
if (ESBYTE[bufpos] == '/') {
|
||||
opened = false;
|
||||
bufpos++;
|
||||
} else {
|
||||
opened = true;
|
||||
}
|
||||
|
||||
closepos = strchr(bufpos, '>');
|
||||
whitepos = strchrw(bufpos, bufend-bufpos);
|
||||
|
||||
if (!whitepos) || (whitepos > closepos) {
|
||||
//no param
|
||||
strncpy(#name, bufpos, math.min(closepos - bufpos, sizeof(tag.name)-1));
|
||||
bufpos = closepos;
|
||||
} else {
|
||||
//we have param
|
||||
while (chrlnum(whitepos, '\"', closepos - whitepos)%2) { //alt="Next>>"
|
||||
if (!openpos = strchr(closepos+1, '<')) break;
|
||||
if (openpos < strchr(closepos+1, '>')) break;
|
||||
if (!closepos = EAX) {closepos = bufend;break;}
|
||||
}
|
||||
strncpy(#name, bufpos, math.min(whitepos - bufpos, sizeof(tag.name)-1));
|
||||
bufpos = closepos;
|
||||
|
||||
params = malloc(closepos - whitepos + 1);
|
||||
strncpy(params, whitepos, closepos - whitepos);
|
||||
paramsend = params + closepos - whitepos;
|
||||
while (paramsend = get_next_param(params, paramsend-1));
|
||||
free(params);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
strlwr(#name);
|
||||
// ignore text inside the next tags
|
||||
if (is("script")) || (is("style")) || (is("binary")) || (is("select")) {
|
||||
strcpy(#prior, #name);
|
||||
sprintf(#name, "</%s>", #prior);
|
||||
if (strstri(bufpos, #name)) bufpos = EAX-1;
|
||||
retok = false;
|
||||
} else {
|
||||
if (name[strlen(#name)-1]=='/') name[strlen(#name)-1]=NULL; //for <br/>
|
||||
}
|
||||
} else {
|
||||
retok = false;
|
||||
}
|
||||
|
||||
_RET:
|
||||
ESDWORD[_bufpos] = bufpos;
|
||||
return retok;
|
||||
}
|
||||
|
||||
dword _tag::get_next_param(dword ps, pe)
|
||||
{
|
||||
// "ps" - param start
|
||||
// "pe" - param end
|
||||
// "q" - quote char
|
||||
char q = NULL;
|
||||
dword initial_pe = pe;
|
||||
dword fixeq;
|
||||
dword val;
|
||||
dword attr;
|
||||
|
||||
if (ESBYTE[pe] == '/') pe--;
|
||||
while (pe>ps) && (__isWhite(ESBYTE[pe])) pe--;
|
||||
|
||||
if (ESBYTE[pe] == '"') || (ESBYTE[pe] == '\'')
|
||||
{
|
||||
//remove quote
|
||||
q = ESBYTE[pe];
|
||||
ESBYTE[pe] = '\0';
|
||||
pe--;
|
||||
|
||||
//find VAL start and copy
|
||||
pe = strrchr(ps, q) + ps;
|
||||
val = pe;
|
||||
if (pe>ps) pe--;
|
||||
ESBYTE[pe] = '\0';
|
||||
|
||||
//find ATTR end
|
||||
while (pe > ps) && (ESBYTE[pe] != '=') pe--;
|
||||
ESBYTE[pe] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
//find VAL start and copy
|
||||
while (pe > ps) && (ESBYTE[pe] != '=') pe--;
|
||||
val = pe+1;
|
||||
ESBYTE[pe] = '\0';
|
||||
//already have ATTR end
|
||||
}
|
||||
|
||||
if (pe > ps) pe--;
|
||||
|
||||
//Fix case: "src ="
|
||||
while (pe>ps) && (__isWhite(ESBYTE[pe])) {
|
||||
ESBYTE[pe] = '\0';
|
||||
pe--;
|
||||
}
|
||||
|
||||
//find ATTR start and copy
|
||||
while (pe>ps) && (!__isWhite(ESBYTE[pe])) pe--;
|
||||
attr = pe + 1;
|
||||
ESBYTE[pe] = '\0';
|
||||
|
||||
// Fix case: src=./images/logo?sid=e8ece8b38b
|
||||
// Exchange '=' and '\0' position.
|
||||
// attr: src=./images/logo?sid => src
|
||||
// val: e8ece8b38b => ./images/logo?sid=e8ece8b38b
|
||||
fixeq = strchr(attr,'=');
|
||||
if (!q) && (fixeq) {
|
||||
ESBYTE[val-1] >< ESBYTE[fixeq];
|
||||
val = fixeq+1;
|
||||
}
|
||||
strlwr(attr);
|
||||
strrtrim(val);
|
||||
//Fix case: " img.png"
|
||||
while(__isWhite(ESBYTE[val])) && (val<initial_pe) val++;
|
||||
|
||||
attributes.add(attr);
|
||||
values.add(val);
|
||||
|
||||
if (pe==ps) return NULL;
|
||||
return pe;
|
||||
}
|
||||
|
||||
dword _tag::get_value_of(dword _attr_name)
|
||||
{
|
||||
int pos = attributes.get_pos_by_name(_attr_name);
|
||||
if (pos == -1) {
|
||||
value = 0;
|
||||
} else {
|
||||
value = values.get(pos);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
signed _tag::get_number_of(dword _attr_name)
|
||||
{
|
||||
if (get_value_of(_attr_name)) {
|
||||
number = atoi(value);
|
||||
} else {
|
||||
number = 0;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -1,184 +0,0 @@
|
||||
CANVAS canvas;
|
||||
|
||||
void TWebBrowser::RenderLine(dword _line)
|
||||
{
|
||||
unsigned px; //paint x coordinate
|
||||
unsigned pw; //paint y coordinate
|
||||
dword pc; //paint color
|
||||
int zoom;
|
||||
|
||||
if (style.title)
|
||||
{
|
||||
strncpy(#header, _line, sizeof(TWebBrowser.header)-1);
|
||||
strncat(#header, " - ", sizeof(TWebBrowser.header)-1);
|
||||
strncat(#header, #version, sizeof(TWebBrowser.header)-1);
|
||||
}
|
||||
else if (t_html) && (!t_body) {
|
||||
//
|
||||
}
|
||||
else if (ESBYTE[_line])
|
||||
{
|
||||
pw = strlen(_line) * list.font_w;
|
||||
zoom = list.font_w / BASIC_CHAR_W;
|
||||
|
||||
//there is some shit happens!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
if (debug_mode) && (pw > draw_w + BODY_MARGIN) {
|
||||
debugln("anomaly");
|
||||
debugln(_line);
|
||||
}
|
||||
|
||||
if (debug_mode) {
|
||||
canvas.DrawBar(draw_x, draw_y, pw, list.item_h, 0xCCCccc);
|
||||
debugln(_line);
|
||||
}
|
||||
|
||||
style.cur_line_h = math.max(style.cur_line_h, list.item_h);
|
||||
|
||||
if (!secondrun) goto _SKIP_DRAW;
|
||||
if (bg_colors.get_last() - bg_colors.get(0)) {
|
||||
canvas.DrawBar(draw_x, draw_y, pw, list.item_h, bg_colors.get_last());
|
||||
}
|
||||
|
||||
if (style.image) {
|
||||
canvas.DrawBar(draw_x, draw_y, pw, list.item_h-1, 0xF9DBCB);
|
||||
}
|
||||
if (style.button) {
|
||||
canvas.DrawBar(draw_x, draw_y, pw, list.item_h - calc(zoom*2), 0xCCCccc);
|
||||
canvas.DrawBar(draw_x, draw_y + list.item_h - calc(zoom*2), pw, zoom, 0x999999);
|
||||
}
|
||||
|
||||
pc = text_colors.get_last();
|
||||
if (link) && (pc == text_colors.get(0)) pc = link_color_default;
|
||||
|
||||
canvas.WriteText(draw_x, draw_y+1, list.font_type, pc, _line, NULL);
|
||||
if (style.b) canvas.WriteText(draw_x+1, draw_y+1, list.font_type, pc, _line, NULL);
|
||||
if (style.s) canvas.DrawBar(draw_x, list.item_h / 2 - zoom + draw_y, pw, zoom, pc);
|
||||
if (style.u) canvas.DrawBar(draw_x, draw_y + list.font_h, pw, zoom, pc);
|
||||
if (link) {
|
||||
if (ESBYTE[_line]==' ') && (ESBYTE[_line+1]==NULL) {} else {
|
||||
canvas.DrawBar(draw_x, draw_y + list.font_h, pw, zoom, link_color_default);
|
||||
links.add_text(draw_x, draw_y + list.y, pw, list.font_h, zoom);
|
||||
}
|
||||
}
|
||||
_SKIP_DRAW:
|
||||
draw_x += pw;
|
||||
}
|
||||
ESBYTE[_line] = NULL;
|
||||
}
|
||||
|
||||
void TWebBrowser::RenderTextbuf()
|
||||
{
|
||||
dword lbp = #linebuf;
|
||||
int br; //break position
|
||||
char nul = '\0';
|
||||
unsigned int len;
|
||||
|
||||
//Do we need a line break?
|
||||
|
||||
if (!linebuf[0]) return;
|
||||
|
||||
while (len = strlen(lbp)) && (len * list.font_w + draw_x - left_gap >= draw_w) {
|
||||
//Yes, we do. Lets calculate where...
|
||||
br = len;
|
||||
|
||||
//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 + left_gap - BODY_MARGIN / list.font_w;
|
||||
if (br < 0) br = 0;
|
||||
while(br) {
|
||||
if (ESBYTE[lbp + br]==' ') || (ESBYTE[lbp + br]=='-') {
|
||||
if (br < len) br++;
|
||||
break;
|
||||
}
|
||||
br--;
|
||||
}
|
||||
}
|
||||
//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) {
|
||||
br = draw_w - draw_x + left_gap - BODY_MARGIN / list.font_w;
|
||||
if (br < 0) {
|
||||
NewLine();
|
||||
br = draw_w - draw_x + left_gap - BODY_MARGIN / list.font_w;
|
||||
}
|
||||
}
|
||||
|
||||
if (br) {
|
||||
ESBYTE[lbp + br] >< nul;
|
||||
RenderLine(lbp);
|
||||
ESBYTE[lbp + br] >< nul;
|
||||
lbp += br;
|
||||
while (ESBYTE[lbp]==' ') && (ESBYTE[lbp]) lbp++;
|
||||
if (ESBYTE[lbp]) NewLine();
|
||||
} else {
|
||||
NewLine();
|
||||
}
|
||||
}
|
||||
RenderLine(lbp);
|
||||
}
|
||||
|
||||
void TWebBrowser::NewLine()
|
||||
{
|
||||
static bool empty_line = true;
|
||||
|
||||
if (draw_x==left_gap) && (draw_y==BODY_MARGIN) return;
|
||||
if (t_html) && (!t_body) return;
|
||||
|
||||
if (draw_x == style.tag_list.level * 5 * list.font_w + left_gap) {
|
||||
if (!empty_line) {
|
||||
empty_line=true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
empty_line = false;
|
||||
}
|
||||
|
||||
draw_y += style.cur_line_h;
|
||||
style.cur_line_h = list.item_h;
|
||||
if (style.blq) draw_x = 6 * list.font_w; else draw_x = 0; //left_gap += style.tag_list.level * 5 * list.font_w ???
|
||||
draw_x += style.tag_list.level * 5 * list.font_w + left_gap;
|
||||
}
|
||||
|
||||
bool TWebBrowser::RenderImage(dword cur_img)
|
||||
{
|
||||
int img_x, img_y, img_w, img_h;
|
||||
dword imgbuf[44];
|
||||
|
||||
if (!cur_img) || (!buf_data) return false;
|
||||
|
||||
img_h = ESDWORD[cur_img+8];
|
||||
img_w = ESDWORD[cur_img+4];
|
||||
|
||||
if (img_w + draw_x - left_gap >= draw_w) NewLine();
|
||||
img_y = draw_y;
|
||||
if (img_h < list.item_h) img_y += list.item_h - img_h / 2 - 1; else img_y -= 2;
|
||||
style.cur_line_h = math.max(style.cur_line_h, img_h);
|
||||
|
||||
img_w = math.min(img_w, canvas.bufw - draw_x);
|
||||
|
||||
if (link) links.add_text(draw_x + list.x, img_y + list.y, img_w, img_h, 0);
|
||||
|
||||
if (img_y + img_h >= canvas.bufh) canvas.IncreaseBufSize();
|
||||
|
||||
if (secondrun)
|
||||
{
|
||||
if (ESDWORD[cur_img+20] != IMAGE_BPP32) {
|
||||
img_convert stdcall(cur_img, 0, IMAGE_BPP32, 0, 0);
|
||||
$push eax
|
||||
img_destroy stdcall(cur_img);
|
||||
$pop eax
|
||||
cur_img = EAX;
|
||||
if (!EAX) return false;
|
||||
}
|
||||
imgbuf[04] = canvas.bufw;
|
||||
imgbuf[08] = canvas.bufh;
|
||||
imgbuf[20] = IMAGE_BPP32;
|
||||
imgbuf[24] = buf_data+8;
|
||||
img_blend stdcall(#imgbuf, cur_img, draw_x, img_y, 0, 0, img_w, img_h);
|
||||
img_destroy stdcall(cur_img);
|
||||
}
|
||||
|
||||
draw_x += img_w;
|
||||
if (draw_x - left_gap >= draw_w) NewLine();
|
||||
return true;
|
||||
}
|
||||
@@ -1,513 +0,0 @@
|
||||
void TWebBrowser::SetStyle()
|
||||
{
|
||||
if (tag.get_value_of("name")) || (tag.get_value_of("id")) {
|
||||
anchors.add(tag.value, draw_y);
|
||||
if (anchors.current) && (streq(tag.value, #anchors.current+1)) {
|
||||
list.first = draw_y;
|
||||
anchors.current = NULL;
|
||||
}
|
||||
}
|
||||
if (tag.is("a")) { tag_a(); return; }
|
||||
if (tag.is("p")) { tag_p(); return; }
|
||||
if (tag.is("img")) { tag_img(); return; }
|
||||
if (tag.is("kosicon")) { tag_kosicon(); return; }
|
||||
if (tag.is("div")) { tag_div(); return; }
|
||||
if (tag.is("br")) { /*draw_x++;*/NewLine(); return; }
|
||||
if (tag.is("nav")) { style.nav = tag.opened; return; }
|
||||
if (tag.is("header")) { NewLine(); return; }
|
||||
if (tag.is("article")) { NewLine(); return; }
|
||||
if (tag.is("footer")) { NewLine(); return; }
|
||||
if (tag.is("figure")) { NewLine(); return; }
|
||||
if (tag.is("w:p")) { NewLine(); return; }
|
||||
if (tag.is("b")) { style.b = tag.opened; return; }
|
||||
if (tag.is("strong")) { style.b = tag.opened; return; }
|
||||
if (tag.is("big")) { style.b = tag.opened; return; }
|
||||
if (tag.is("w:b")) { style.b = tag.opened; return; }
|
||||
if (tag.is("u")) { style.u = tag.opened; return; }
|
||||
if (tag.is("ins")) { style.u = tag.opened; return; }
|
||||
if (tag.is("s")) { style.s = tag.opened; return; }
|
||||
if (tag.is("strike")) { style.s = tag.opened; return; }
|
||||
if (tag.is("del")) { style.s = tag.opened; return; }
|
||||
if (tag.is("pre")) { style.pre = tag.opened; return; }
|
||||
if (tag.is("blockquote")) { style.blq = tag.opened; return; }
|
||||
if (tag.is("button")) { style.button = tag.opened; return; }
|
||||
if (tag.is("dl")) { if (tag.opened) NewLine(); return; }
|
||||
if (tag.is("w:r")) { if (!tag.opened) style.b = false; return; }
|
||||
if (tag.is("h1")) { tag_h1234_caption(); return; }
|
||||
if (tag.is("h2")) { tag_h1234_caption(); return; }
|
||||
if (tag.is("h3")) { tag_h1234_caption(); return; }
|
||||
if (tag.is("h4")) { tag_h1234_caption(); return; }
|
||||
if (tag.is("font")) { tag_font(); return; }
|
||||
if (tag.is("dt")) { tag_ol_ul_dt(); return; }
|
||||
if (tag.is("dd")) { tag_ol_ul_dt(); return; }
|
||||
if (tag.is("ul")) { tag_ol_ul_dt(); return; }
|
||||
if (tag.is("ol")) { tag_ol_ul_dt(); return; }
|
||||
if (tag.is("li")) { tag_li(); return; }
|
||||
if (tag.is("q")) { tag_q(); return; }
|
||||
if (tag.is("hr")) { tag_hr(); return; }
|
||||
if (tag.is("meta")) { tag_meta_xml(); return; }
|
||||
if (tag.is("?xml")) { tag_meta_xml(); return; }
|
||||
if (tag.is("code")) { tag_code(); return; }
|
||||
if (tag.is("iframe")) { tag_iframe(); return; }
|
||||
if (tag.is("caption")) { tag_h1234_caption(); return; }
|
||||
if (tag.is("title")) { tag_title(); return; }
|
||||
if (tag.is("body")) { tag_body(); return; }
|
||||
if (tag.is("html")) { t_html = tag.opened; return; }
|
||||
if (tag.is("table")) { tag_table(); return; }
|
||||
if (tag.is("tr")) { tag_table(); return; }
|
||||
if (tag.is("th")) { tag_table(); return; }
|
||||
if (tag.is("td")) { tag_table(); return; }
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_p()
|
||||
{
|
||||
IF (tag.prior[0] == 'h') || (streq(#tag.prior,"td")) return;
|
||||
IF (!tag.opened) && (streq(#tag.prior,"p")) return;
|
||||
NewLine();
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_title()
|
||||
{
|
||||
style.title = tag.opened;
|
||||
if (!tag.opened) DrawTitle(#header);
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_font()
|
||||
{
|
||||
style.font = tag.opened;
|
||||
if (tag.opened)
|
||||
{
|
||||
if (tag.get_value_of("bg")) {
|
||||
bg_colors.add(GetColor(tag.value));
|
||||
} else {
|
||||
bg_colors.add(bg_colors.get_last());
|
||||
}
|
||||
if (tag.get_value_of("color")) {
|
||||
text_colors.add(GetColor(tag.value));
|
||||
} else {
|
||||
text_colors.add(text_colors.get_last());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (text_colors.count>1) text_colors.pop();
|
||||
if (bg_colors.count>1) bg_colors.pop(); //never pop the last color
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_div()
|
||||
{
|
||||
//if (streq(#tag.prior,"div")) && (tag.opened) return;
|
||||
if (streq(#tag.prior,"td")) return;
|
||||
if (streq(#tag.prior,"div")) return;
|
||||
if (!tag.opened) && (style.font) text_colors.pop();
|
||||
NewLine();
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_iframe()
|
||||
{
|
||||
if (tag.get_value_of("src")) {
|
||||
NewLine();
|
||||
strcpy(#linebuf, "IFRAME: ");
|
||||
RenderTextbuf();
|
||||
link=true;
|
||||
links.add_link(tag.value);
|
||||
strncpy(#linebuf, tag.value, sizeof(TWebBrowser.linebuf)-1);
|
||||
RenderTextbuf();
|
||||
link=false;
|
||||
NewLine();
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_a()
|
||||
{
|
||||
if (!secondrun) return;
|
||||
if (tag.opened)
|
||||
{
|
||||
if (tag.get_value_of("href")) && (!strstr(tag.value,"javascript:"))
|
||||
{
|
||||
link = true;
|
||||
links.add_link(tag.value);
|
||||
}
|
||||
} else {
|
||||
link = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_meta_xml()
|
||||
{
|
||||
if (secondrun) return;
|
||||
if (custom_encoding == -1) if (tag.get_value_of("charset"))
|
||||
|| (tag.get_value_of("content")) || (tag.get_value_of("encoding"))
|
||||
{
|
||||
EDX = strrchr(tag.value, '=') + tag.value; //search in content=
|
||||
if (ESBYTE[EDX] == '"') EDX++;
|
||||
strlwr(EDX);
|
||||
EAX = get_encoding_type_by_name(EDX);
|
||||
if (EAX!=-1) ChangeEncoding(EAX);
|
||||
}
|
||||
if (streq(tag.get_value_of("http-equiv"), "refresh")) && (tag.get_value_of("content")) {
|
||||
if (tag.value = strstri(tag.value, "url")) strcpy(#redirect, tag.value);
|
||||
}
|
||||
}
|
||||
|
||||
signed int get_encoding_type_by_name(dword name)
|
||||
{
|
||||
EDX = name;
|
||||
if (streqrp(EDX,"utf-8")) || (streqrp(EDX,"utf8")) return CH_UTF8;
|
||||
else if (streqrp(EDX,"windows-1251")) || (streqrp(EDX,"windows1251")) return CH_CP1251;
|
||||
else if (streqrp(EDX,"dos")) || (streqrp(EDX,"cp-866")) return CH_CP866;
|
||||
else if (streqrp(EDX,"iso-8859-5")) || (streqrp(EDX,"iso8859-5")) return CH_ISO8859_5;
|
||||
else if (streqrp(EDX,"koi8-r")) || (streqrp(EDX,"koi8-u")) return CH_KOI8;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_code()
|
||||
{
|
||||
if (style.pre = tag.opened) {
|
||||
bg_colors.add(0xe4ffcb);
|
||||
} else {
|
||||
if (bg_colors.count>1) bg_colors.pop(); //never pop the last color
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_ol_ul_dt()
|
||||
{
|
||||
char type = ESBYTE[#tag.name];
|
||||
switch(type)
|
||||
{
|
||||
case 'd':
|
||||
if (ESBYTE[#tag.name+1]=='d') style.tag_list.upd_level(tag.opened, type);
|
||||
if (ESBYTE[#tag.name+1]=='t') style.tag_list.upd_level(false, 'd');
|
||||
if (tag.opened) NewLine();
|
||||
break;
|
||||
case 'u':
|
||||
case 'o':
|
||||
if (style.nav) && (style.tag_list.level) NewLine();
|
||||
style.tag_list.upd_level(tag.opened, type);
|
||||
if (!tag.opened) && (!style.pre) NewLine();
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_li()
|
||||
{
|
||||
if (style.nav) {
|
||||
chrncat(#linebuf, ' ', sizeof(TWebBrowser.linebuf));
|
||||
} else if (tag.opened) {
|
||||
if (!style.tag_list.level) style.tag_list.upd_level(1, 'u');
|
||||
if (!style.pre) NewLine();
|
||||
if (style.tag_list.order_type() == 'u') {
|
||||
strcpy(#linebuf, "\31 ");
|
||||
draw_x = style.tag_list.level * 5 - 2 * list.font_w + left_gap;
|
||||
}
|
||||
if (style.tag_list.order_type() == 'o') {
|
||||
sprintf(#linebuf, "%i. ", style.tag_list.inc_counter());
|
||||
draw_x = style.tag_list.level * 5 - 1 - strlen(#linebuf) * list.font_w + left_gap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_hr()
|
||||
{
|
||||
dword hrcol = 0x00777777;
|
||||
dword hr_width = draw_w-BODY_MARGIN-BODY_MARGIN;
|
||||
dword hr_size = 1;
|
||||
if (tag.get_value_of("color")) {
|
||||
hrcol = GetColor(tag.value);
|
||||
}
|
||||
if (tag.get_value_of("width")) && (!strchr(tag.value, '%')) {
|
||||
hr_width = math.min(hr_width, tag.get_number_of("width"));
|
||||
}
|
||||
if (tag.get_number_of("size")) {
|
||||
hr_size = math.min(500, tag.number);
|
||||
}
|
||||
if (draw_x != left_gap) NewLine();
|
||||
if (secondrun) canvas.DrawBar(left_gap, style.cur_line_h / 2 + draw_y - 1, hr_width, hr_size, hrcol);
|
||||
draw_y += hr_size - 3;
|
||||
draw_x++;
|
||||
NewLine();
|
||||
return;
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_body()
|
||||
{
|
||||
t_body = tag.opened;
|
||||
if (tag.get_value_of("link")) link_color_default = GetColor(tag.value);
|
||||
if (tag.get_value_of("alink")) link_color_active = GetColor(tag.value);
|
||||
if (tag.get_value_of("text")) text_colors.set(0, GetColor(tag.value));
|
||||
if (tag.get_value_of("bgcolor")) bg_colors.set(0, GetColor(tag.value));
|
||||
// Autodetecting encoding if no encoding was set
|
||||
if (tag.opened) && (custom_encoding==-1) && (cur_encoding == CH_CP866) {
|
||||
if (strstr(bufpointer, "\208\190")) ChangeEncoding(CH_UTF8);
|
||||
else if (chrnum(bufpointer, '\246')>5) ChangeEncoding(CH_CP1251);
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_q()
|
||||
{
|
||||
chrncat(#linebuf, '\"', sizeof(TWebBrowser.linebuf));
|
||||
}
|
||||
|
||||
void TWebBrowser::reset_font_style()
|
||||
{
|
||||
list.SetFont(BASIC_CHAR_W, 14, 10011000b);
|
||||
style.cur_line_h = list.item_h = list.font_h + 5;
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_h1234_caption()
|
||||
{
|
||||
if (ESBYTE[#tag.name+1]=='4') {
|
||||
NewLine();
|
||||
NewLine();
|
||||
style.h = tag.opened;
|
||||
style.b = tag.opened;
|
||||
} else {
|
||||
style.h = tag.opened;
|
||||
if (tag.opened) {
|
||||
if (!style.pre) {
|
||||
NewLine();
|
||||
NewLine();
|
||||
}
|
||||
if (tag.is("h1")) {
|
||||
list.SetFont(BASIC_CHAR_W*2, 14+13, 10011001b);
|
||||
style.b = true;
|
||||
} else if (tag.is("h2")) {
|
||||
list.SetFont(BASIC_CHAR_W*2, 14+13, 10011001b);
|
||||
} else {
|
||||
list.SetFont(6*2, 9+8, 10001001b);
|
||||
}
|
||||
style.cur_line_h = list.item_h = list.font_h + 3;
|
||||
} else {
|
||||
if (tag.is("h1")) style.b = false;
|
||||
NewLine();
|
||||
reset_font_style();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_kosicon()
|
||||
{
|
||||
dword imgbuf[44];
|
||||
dword maxicon;
|
||||
dword shared_i18 = memopen("ICONS18", NULL, SHM_READ);
|
||||
maxicon = EDX / 18 / 18 / 4;
|
||||
if (shared_i18) && (tag.get_number_of("n")) {
|
||||
if (tag.number < maxicon) {
|
||||
if (draw_x + 18 > canvas.bufw) NewLine();
|
||||
canvas.DrawImage(draw_x, draw_y-1, 18, 18, 18*18*4*tag.number+shared_i18);
|
||||
draw_x += 22;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_img()
|
||||
{
|
||||
char img_path[4096]=0;
|
||||
dword base64img;
|
||||
|
||||
if (!tag.get_value_of("data-large-image"))
|
||||
if (!tag.get_value_of("data-src"))
|
||||
if (!tag.get_value_of("src")) return;
|
||||
|
||||
if (streqrp(tag.value, "data:")) {
|
||||
if (!strstr(tag.value, "base64,")) goto NOIMG;
|
||||
EDX = EAX+7;
|
||||
if (ESBYTE[EDX]==' ') EDX++;
|
||||
base64img = malloc(strlen(EDX));
|
||||
base64_decode stdcall (EDX, base64img, strlen(EDX));
|
||||
img_decode stdcall (base64img, EAX, 0);
|
||||
$push eax
|
||||
free(base64img);
|
||||
$pop eax
|
||||
if (EAX) goto IMGOK; else goto NOIMG;
|
||||
}
|
||||
|
||||
if (!strcmp(tag.value + strrchr(tag.value, '.'), "svg")) goto NOIMG;
|
||||
if (!strcmp(tag.value + strrchr(tag.value, '.'), "webp")) goto NOIMG;
|
||||
|
||||
strlcpy(#img_path, tag.value, sizeof(img_path)-1);
|
||||
replace_char(#img_path, ' ', '\0', sizeof(img_path)-1);
|
||||
get_absolute_url(#img_path, history.current());
|
||||
|
||||
if (check_is_the_adress_local(#img_path)) {
|
||||
img_from_file stdcall(#img_path);
|
||||
if (EAX) goto IMGOK; else goto NOIMG;
|
||||
}
|
||||
|
||||
if (cache.has(#img_path)) {
|
||||
img_decode stdcall (cache.current_buf, cache.current_size, 0);
|
||||
if (EAX) goto IMGOK; else goto NOIMG;
|
||||
} else {
|
||||
if (img_url.get_pos_by_name(#img_path)==-1) img_url.add(#img_path);
|
||||
goto NOIMG;
|
||||
}
|
||||
|
||||
IMGOK:
|
||||
if (RenderImage(EAX)) return;
|
||||
|
||||
NOIMG:
|
||||
if (tag.get_value_of("title")) || (tag.get_value_of("alt")) {
|
||||
strncpy(#img_path, tag.value, sizeof(TWebBrowser.linebuf)-3);
|
||||
sprintf(#linebuf, "[%s]", #img_path);
|
||||
} else {
|
||||
if (streqrp(#img_path, "data:")) img_path=0;
|
||||
replace_char(#img_path, '?', NULL, strlen(#img_path));
|
||||
img_path[sizeof(TWebBrowser.linebuf)-3] = '\0'; //prevent overflow in sprintf
|
||||
sprintf(#linebuf, "[%s]", #img_path+strrchr(#img_path, '/'));
|
||||
linebuf[50]= NULL;
|
||||
}
|
||||
text_colors.add(0x9A6F29);
|
||||
style.image = true;
|
||||
RenderTextbuf();
|
||||
style.image = false;
|
||||
text_colors.pop();
|
||||
}
|
||||
|
||||
struct TABLE {
|
||||
int depth;
|
||||
int margin;
|
||||
collection_int cols;
|
||||
} table;
|
||||
|
||||
unsigned table_id;
|
||||
unsigned colcount;
|
||||
unsigned tr_pos;
|
||||
unsigned td_pos;
|
||||
unsigned row_start_y;
|
||||
unsigned tallest_cell_in_row;
|
||||
unsigned cur_cell_w;
|
||||
|
||||
void TWebBrowser::tag_table_reset()
|
||||
{
|
||||
table_id = 0;
|
||||
colcount = 0;
|
||||
tr_pos = 0;
|
||||
td_pos = 0;
|
||||
table.depth = 0;
|
||||
cur_cell_w = 0;
|
||||
}
|
||||
|
||||
void TWebBrowser::tag_table()
|
||||
{
|
||||
if (!tag.opened) {
|
||||
if (style.font) tag_font();
|
||||
if (link) tag_a();
|
||||
style.b = false;
|
||||
}
|
||||
if (tag.is("table")) {
|
||||
if(tag.opened) {
|
||||
table.depth++;
|
||||
if (table.depth==1) {
|
||||
table_id++;
|
||||
colcount = 0;
|
||||
td_pos = 0;
|
||||
row_start_y = draw_y;
|
||||
if (tag.get_number_of("width")) {
|
||||
if (strchr(tag.value, '%')) tag.number = list.w * tag.number / 100;
|
||||
cur_cell_w = math.min(tag.number,list.w);
|
||||
} else {
|
||||
cur_cell_w = list.w;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (table.depth>0) {
|
||||
table.depth--;
|
||||
}
|
||||
if (table.depth==0) {
|
||||
draw_x = left_gap = style.tag_list.level * 5 * list.font_w + BODY_MARGIN;
|
||||
draw_w = list.w;
|
||||
if (td_pos) draw_y = math.max(draw_y, tallest_cell_in_row);
|
||||
draw_y = math.max(draw_y+style.cur_line_h, tallest_cell_in_row);
|
||||
row_start_y = tallest_cell_in_row = draw_y;
|
||||
style.cur_line_h = list.item_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (table.depth>1) {
|
||||
if (tag.is("tr")) && (tag.opened) NewLine();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!secondrun) {
|
||||
if (tag.is("tr")) {
|
||||
if (tag.opened) {
|
||||
table.cols.add(1);
|
||||
}
|
||||
colcount = 0;
|
||||
}
|
||||
if (tag.opened) if (tag.is("td")) || (tag.is("th")) {
|
||||
if (!table.cols.count) { table.cols.add(1); colcount = 0;}
|
||||
colcount++;
|
||||
if (colcount) table.cols.set(table.cols.count-1, colcount);
|
||||
//if (tag.get_number_of("colspan")) colcount += tag.number-1;
|
||||
}
|
||||
} else {
|
||||
if (tag.is("tr")) {
|
||||
if (tag.opened) {
|
||||
if (td_pos) draw_y = math.max(draw_y, tallest_cell_in_row);
|
||||
_TR_FIX:
|
||||
if (draw_x==left_gap) && (draw_y==BODY_MARGIN) {
|
||||
row_start_y = tallest_cell_in_row = draw_y;
|
||||
} else {
|
||||
row_start_y = tallest_cell_in_row = draw_y = draw_y + style.cur_line_h;
|
||||
}
|
||||
style.cur_line_h = list.item_h;
|
||||
tr_pos++;
|
||||
td_pos = 0;
|
||||
} else {
|
||||
draw_y = math.max(draw_y, tallest_cell_in_row);
|
||||
td_pos = 0;
|
||||
}
|
||||
draw_x = left_gap = style.tag_list.level * 5 * list.font_w + BODY_MARGIN;
|
||||
draw_w = list.w;
|
||||
}
|
||||
if (tag.is("td")) || (tag.is("th")) {
|
||||
|
||||
if (!tr_pos) goto _TR_FIX;
|
||||
|
||||
tallest_cell_in_row = math.max(draw_y+style.cur_line_h-list.item_h+1, tallest_cell_in_row);
|
||||
style.cur_line_h = list.item_h;
|
||||
if (tag.opened)
|
||||
{
|
||||
if (!td_pos) {
|
||||
table.margin = list.w - cur_cell_w / 2 + BODY_MARGIN;
|
||||
draw_x = left_gap = table.margin;
|
||||
draw_w = cur_cell_w - BODY_MARGIN;
|
||||
} else {
|
||||
draw_x = left_gap = left_gap + draw_w;
|
||||
draw_w = cur_cell_w - left_gap + table.margin - BODY_MARGIN;
|
||||
}
|
||||
|
||||
if (EAX = table.cols.get(tr_pos-1)-td_pos) {
|
||||
draw_w /= EAX;
|
||||
} else {
|
||||
draw_y = row_start_y;
|
||||
draw_x = left_gap = table.margin;
|
||||
}
|
||||
if (table.cols.get(tr_pos-1)-td_pos>1) && (tag.get_number_of("width")) {
|
||||
if (strchr(tag.value, '%')) {
|
||||
tag.number = cur_cell_w * tag.number / 100; //
|
||||
}
|
||||
if (tag.number < list.w - table.margin - left_gap) draw_w = tag.number;
|
||||
|
||||
}
|
||||
draw_y = row_start_y;
|
||||
td_pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (draw_x > cur_cell_w) {
|
||||
draw_x = left_gap = table.margin;
|
||||
draw_w = cur_cell_w - table.margin - 23 - left_gap;
|
||||
table.depth = 0;
|
||||
NewLine();
|
||||
if (debug_mode) {
|
||||
debugln("anomaly draw_x");
|
||||
canvas.DrawBar(0, draw_y, 20, 20, 0xFF0000);
|
||||
}
|
||||
}
|
||||
//if (left_gap + draw_w > list.w) {
|
||||
// draw_w = list.w - left_gap;
|
||||
// if (debug_mode) debugln("anomaly draw_W");
|
||||
//}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
char *unicode_symbols[]={
|
||||
"quot","\"",
|
||||
"amp", "&",
|
||||
"lt", "<",
|
||||
"gt", ">",
|
||||
"#183","\31", "middot", "\31",
|
||||
"#149","-",
|
||||
"#151","-",
|
||||
"#160"," ", "nbsp", "\t", "emsp", " ",
|
||||
"#169","(c)", "copy", "(c)",
|
||||
"#171","<<", "laquo","<<",
|
||||
"#174","(r)", "reg", "(r)",
|
||||
"#187",">>", "raquo",">>",
|
||||
"hellip", "...",
|
||||
|
||||
"trade", "[TM]",
|
||||
"bdquo", ",,",
|
||||
|
||||
"minus", "-",
|
||||
"ndash", "-",
|
||||
"mdash", "-", //--
|
||||
|
||||
"rsquo", "'", "apos", "'",
|
||||
"sect", "#",
|
||||
|
||||
"ensp", " ",
|
||||
"emsp13", " ",
|
||||
"emsp14", " ",
|
||||
"numsp", " ",
|
||||
"puncsp", " ",
|
||||
"thinsp", " ",
|
||||
|
||||
"#1028", "\242",
|
||||
"#1030", "I",
|
||||
"#1031", "\244",
|
||||
|
||||
"#8211", "-",
|
||||
"#8212", "-",
|
||||
"#8217", "'",
|
||||
"#8220", "\"",
|
||||
"#8222", "\"", "ldquo", "\"",
|
||||
"#8221", "\"", "rdquo", "\"",
|
||||
"#8470", "N",
|
||||
"#8722", "-",
|
||||
"#9642", "-", //square in the middle of the line
|
||||
"#9658", ">",
|
||||
"#9660", "v",
|
||||
"#10094", "<",
|
||||
"#10095", ">",
|
||||
"#65122", "+",
|
||||
|
||||
"#8594", "->",
|
||||
"#8627", "->",
|
||||
|
||||
"uarr", "^",
|
||||
"darr", "v",
|
||||
"rarr", "->",
|
||||
"larr", "<-",
|
||||
|
||||
"bull", "\31",
|
||||
"percnt","%",
|
||||
|
||||
"#xfeff", "",
|
||||
|
||||
"times", "x",
|
||||
"lowast","*",
|
||||
|
||||
"#128154","<3",
|
||||
"#128545",":(",
|
||||
|
||||
0};
|
||||
|
||||
|
||||
unsigned char unicode_chars[] = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяЁёhг\243i\105\244\0";
|
||||
|
||||
bool GetUnicodeSymbol(dword _line, line_size, bufpos, buf_end)
|
||||
{
|
||||
int i;
|
||||
int code;
|
||||
char special_code[10];
|
||||
bool white_end = false;
|
||||
dword bufstart = bufpos;
|
||||
|
||||
for (i=0; i<9; i++, bufpos++)
|
||||
{
|
||||
if (__isWhite(ESBYTE[bufpos])) {bufpos--; break;}
|
||||
if (ESBYTE[bufpos] == ';') || (bufpos >= buf_end) break;
|
||||
if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#", ESBYTE[bufpos])) {bufpos--; break;}
|
||||
special_code[i] = ESBYTE[bufpos];
|
||||
}
|
||||
special_code[i] = '\0';
|
||||
|
||||
for (i=0; unicode_symbols[i]!=0; i+=2;)
|
||||
{
|
||||
if (!strcmp(#special_code, unicode_symbols[i]))
|
||||
{
|
||||
strncat(_line, unicode_symbols[i+1], line_size);
|
||||
return bufpos;
|
||||
}
|
||||
}
|
||||
|
||||
if (special_code[0]=='#')
|
||||
{
|
||||
code = atoi(#special_code + 1);
|
||||
if (code>=0) && (code<=255) {
|
||||
chrncat(_line, code, line_size); //NOT ALL ASCII CODES IN KOLIBRI ARE COMPATABLE WITH STANDARDS
|
||||
return bufpos;
|
||||
}
|
||||
if (code>=1040) && (code<=1040+72) {
|
||||
chrncat(_line, unicode_chars[code-1040], line_size);
|
||||
return bufpos;
|
||||
}
|
||||
}
|
||||
|
||||
chrncat(_line, '&', line_size);
|
||||
return bufstart;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
struct LIST
|
||||
{
|
||||
int level;
|
||||
char ordered[5];
|
||||
int counter[5];
|
||||
void reset();
|
||||
void upd_level();
|
||||
int inc_counter();
|
||||
char order_type();
|
||||
};
|
||||
|
||||
void LIST::reset()
|
||||
{
|
||||
level = 0;
|
||||
}
|
||||
|
||||
void LIST::upd_level(int direction, char type)
|
||||
{
|
||||
if (direction == 1) && (level<5) {
|
||||
level++;
|
||||
counter[level] = 0;
|
||||
ordered[level] = type;
|
||||
}
|
||||
if (direction == 0) && (level>0) {
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
int LIST::inc_counter()
|
||||
{
|
||||
counter[level]++;
|
||||
return counter[level];
|
||||
}
|
||||
|
||||
char LIST::order_type()
|
||||
{
|
||||
return ordered[level];
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("WebView.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "WebView.com")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
@c-- /D=LANG_RUS WebView.c
|
||||
@del WebView
|
||||
@rename WebView.com WebView
|
||||
@del warning.txt
|
||||
|
||||
if not exist WebView ( @pause )
|
||||
|
||||
if exist WebView (
|
||||
"C:\Program Files (x86)\WinImage\winimage.exe" "C:\Users\leency\Desktop\kolibri.img" /H /Q /I WebView
|
||||
d:
|
||||
cd "D:\Kolibri\Infrastructure\QEMU"
|
||||
call "C:\Users\leency\Desktop\qemu.bat"
|
||||
) else (
|
||||
pause
|
||||
)
|
||||
@@ -1 +0,0 @@
|
||||
c-- -D=LANG_ENG WebView.c
|
||||
@@ -1,64 +0,0 @@
|
||||
enum {
|
||||
PAGE=1, IMG, FILE
|
||||
};
|
||||
|
||||
struct _cache
|
||||
{
|
||||
dword current_buf;
|
||||
dword current_size;
|
||||
dword current_type;
|
||||
dword current_charset;
|
||||
collection url;
|
||||
collection_int data;
|
||||
collection_int size;
|
||||
collection_int type;
|
||||
collection_int charset;
|
||||
void add();
|
||||
bool has();
|
||||
void clear();
|
||||
} cache;
|
||||
|
||||
void _cache::add(dword _url, _data, _size, _type, _charset)
|
||||
{
|
||||
dword data_pointer;
|
||||
data_pointer = malloc(_size);
|
||||
memmov(data_pointer, _data, _size);
|
||||
data.add(data_pointer);
|
||||
|
||||
url.add(_url);
|
||||
size.add(_size);
|
||||
type.add(_type);
|
||||
charset.add(_charset);
|
||||
|
||||
current_buf = data_pointer;
|
||||
current_size = _size;
|
||||
}
|
||||
|
||||
bool _cache::has(dword _link)
|
||||
{
|
||||
int pos;
|
||||
if (!url.count) return false;
|
||||
pos = url.get_pos_by_name(_link);
|
||||
if (pos != -1) {
|
||||
current_buf = data.get(pos);
|
||||
current_size = size.get(pos);
|
||||
current_type = type.get(pos);
|
||||
current_charset = charset.get(pos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _cache::clear()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<data.count; i++) free(data.get(i));
|
||||
url.drop();
|
||||
data.drop();
|
||||
size.drop();
|
||||
type.drop();
|
||||
current_buf = NULL;
|
||||
current_size = NULL;
|
||||
current_type = NULL;
|
||||
current_charset = NULL;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
#ifdef LANG_RUS
|
||||
//===================================================//
|
||||
// //
|
||||
// CYRILLIC //
|
||||
// //
|
||||
//===================================================//
|
||||
char buildin_page_error[] = FROM "res/page_not_found_ru.htm";
|
||||
char buildin_page_home[] = FROM "res/homepage_ru.htm";
|
||||
char buildin_page_help[] = FROM "res/help_ru.htm";
|
||||
char accept_language[]= "Accept-Language: ru\n";
|
||||
char rmb_menu[] =
|
||||
"Back|Ctrl+<
|
||||
Forward|Ctrl+>
|
||||
-
|
||||
Посмотреть исходник|Ctrl+U
|
||||
Редактировать исходник|F2";
|
||||
char main_menu[] =
|
||||
"Открыть файл...|Ctrl+O
|
||||
Новое окно|Ctrl+N
|
||||
-
|
||||
История|Ctrl+H
|
||||
Менеджер загрузок|Ctrl+J
|
||||
Настройки|Ctrl+E
|
||||
Очистить кэш|Ctrl+F5
|
||||
Обновить браузер";
|
||||
char link_menu[] =
|
||||
"Открыть в новой вкладке
|
||||
Открыть в новом окне
|
||||
-
|
||||
Копировать ссылку
|
||||
Скачать содержимое ссылки";
|
||||
char loading_text[] = "Загрузка...";
|
||||
|
||||
char update_param[] = "-e http://builds.kolibrios.org/ru_RU/data/programs/cmm/browser/WebView.com";
|
||||
char update_download_error[] = "'WebView\nОшибка при получении обновлений!' -tE";
|
||||
char update_ok[] = "'WebView\nБраузер был успешно обновлен!' -tO";
|
||||
char update_is_current[] = "'WebView\nВы уже используете последнюю версию.' -tI";
|
||||
char update_can_not_copy[] = "'WebView\nНе могу переместить новую версию из папки Downloads на Ramdisk. Возможно, не достаточно места.' -tE";
|
||||
char clear_cache_ok[] = "'WebView\nКэш очищен.' -tI";
|
||||
#define T_RENDERING "Рендеринг страницы..."
|
||||
#define T_DONE_IN_SEC "Готово: %i сек (%i милисек)"
|
||||
#else
|
||||
//===================================================//
|
||||
// //
|
||||
// ENGLISH //
|
||||
// //
|
||||
//===================================================//
|
||||
char buildin_page_error[] = FROM "res/page_not_found_en.htm";
|
||||
char buildin_page_home[] = FROM "res/homepage_en.htm";
|
||||
char buildin_page_help[] = FROM "res/help_en.htm";
|
||||
char accept_language[]= "Accept-Language: en\n";
|
||||
char rmb_menu[] =
|
||||
"Back|Ctrl+<
|
||||
Forward|Ctrl+>
|
||||
-
|
||||
View source|Ctrl+U
|
||||
Edit source|F2";
|
||||
char main_menu[] =
|
||||
"Open local file...|Ctrl+O
|
||||
New window|Ctrl+N
|
||||
-
|
||||
History|Ctrl+H
|
||||
Download Manager|Ctrl+J
|
||||
Settings|Ctrl+E
|
||||
Clear cache|Ctrl+F5
|
||||
Update browser";
|
||||
char link_menu[] =
|
||||
"Open in new tab
|
||||
Open in new window
|
||||
-
|
||||
Copy link
|
||||
Download link contents";
|
||||
char loading_text[] = "Loading...";
|
||||
char update_param[] = "-e http://builds.kolibrios.org/en_US/data/programs/cmm/browser/WebView.com";
|
||||
char update_download_error[] = "'WebView\nError receiving update information!' -tE";
|
||||
char update_ok[] = "'WebView\nThe browser has been updated!' -tO";
|
||||
char update_is_current[] = "'WebView\nThe browser is up to date.' -tI";
|
||||
char update_can_not_copy[] = "'WebView\nError copying a new version from Downloads folder!\nProbably too litle space on Ramdisk.' -tE";
|
||||
char clear_cache_ok[] = "'WebView\nThe cache has been cleared.' -tI";
|
||||
#define T_RENDERING "Rendering..."
|
||||
#define T_DONE_IN_SEC "Done in %i sec (%i milisec)"
|
||||
#endif
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// GLOBAL //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
char buildin_page_test[] = FROM "res/test.htm";
|
||||
|
||||
#define URL_SERVICE_HISTORY "WebView:history"
|
||||
#define URL_SERVICE_HOMEPAGE "WebView:home"
|
||||
#define URL_SERVICE_TEST "WebView:test"
|
||||
|
||||
char webview_shared[] = "WEBVIEW";
|
||||
|
||||
enum {
|
||||
NEW_TAB=600,
|
||||
ENCODINGS=700,
|
||||
BACK_BUTTON=800,
|
||||
FORWARD_BUTTON, VIEW_SOURCE, EDIT_SOURCE,
|
||||
REFRESH_BUTTON, GOTOURL_BUTTON, CHANGE_ENCODING,
|
||||
GO_BUTTON, SEARCH_BUTTON, SANDWICH_BUTTON,
|
||||
OPEN_FILE, NEW_WINDOW, VIEW_HISTORY, DOWNLOAD_MANAGER,
|
||||
OPEN_SETTINGS, CLEAR_CACHE, UPDATE_BROWSER, IN_NEW_TAB, IN_NEW_WINDOW,
|
||||
COPY_LINK_URL, DOWNLOAD_LINK_CT, TAB_ID,
|
||||
TAB_CLOSE_ID = 900
|
||||
};
|
||||
|
||||
char editbox_icons[] = FROM "res/editbox_icons.raw";
|
||||
|
||||
#define WIN_W 850
|
||||
#define WIN_H 920
|
||||
|
||||
#define DEFAULT_URL URL_SERVICE_HOMEPAGE
|
||||
|
||||
char version[]="WebView 3.98";
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifdef LANG_RUS
|
||||
#define HISTORY_HEADER "<html><title>История</title><body bgcolor=#fff><h3>Посещенные страницы</h3><br>"
|
||||
#else
|
||||
#define HISTORY_HEADER "<html><title>History</title><body bgcolor=#fff><h3>Visited pages</h3><br>"
|
||||
#endif
|
||||
|
||||
|
||||
ShowHistory()
|
||||
{
|
||||
int i;
|
||||
dword history_pointer = malloc(history.items.data_size+256);
|
||||
strcat(history_pointer, HISTORY_HEADER);
|
||||
|
||||
for (i=0; i<history.items.count-1; i++) //if (cache.type.get(i) == PAGE)
|
||||
{
|
||||
strcat(history_pointer, "<kosicon n=3><a href='");
|
||||
strcat(history_pointer, history.items.get(i));
|
||||
strcat(history_pointer, "'>");
|
||||
strcat(history_pointer, history.items.get(i));
|
||||
strcat(history_pointer, "</a><br>");
|
||||
}
|
||||
|
||||
/*
|
||||
strcat(history_pointer, "<br><b>Cached images</b><br>");
|
||||
for (i=1; i<cache.url.count; i++) if (cache.type.get(i) == IMG)
|
||||
{
|
||||
strcat(history_pointer, cache.url.get(i));
|
||||
strcat(history_pointer, " <img src='");
|
||||
strcat(history_pointer, cache.url.get(i));
|
||||
strcat(history_pointer, "'><br>");
|
||||
}
|
||||
*/
|
||||
|
||||
LoadInternalPage(history_pointer, strlen(history_pointer));
|
||||
free(history_pointer);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1 +0,0 @@
|
||||
▐▐▌бЯЮВБ~xwtВБ~бЯЮ▐▐▌ ╜╗╗ ¤¤¤млк{xuЙЕГСОМЦУССОМЙЕГ{xuмлл╗╗╣rpm нмй~{ПНКЙЕГ~{x{xu|yЙЕГПНККЖДЙЕГxvs ▐▐▌{xuПНКБ|ввЯччх√√√ччхеввКИДЩХТЩХТyxu вЯЯЙЕГЙЕГввЯ ╛╜╗КЖДЩХТЩХТyxu ГБСОМ~{xччх ╜╗╗rpmxvsyxuyxutqo xwtЦУС{xu··· ДБСОМ~{xшчч бЮЭЙЕГЙЕГдба пон}yx┤│▓ ▌▌▌{xuПНКБ|двбччч√√√чччдвб~{ЙЕГ|yv нкк~{ПНКЙЕГ~{x{xu~{xЙЕГПНК~{нлй √√√нкк{xuЙЕГСОМЦУССОМЙЕГ{xuнкк№№№ ▐▌▌вЯЯВБxwtВБвЯЯ▐▌▌ ▄▄▄ ,╨ ,╨ ,╨ФОъ,╨ ,╨ФОъ,╨ ,╨ФОъJA┘JA┘JA┘ JA┘ФОъJA┘JA┘,╨ ,╨JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘,╨ жJA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘,╨ ж жJA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘,╨ ж ,╨JA┘JA┘JA┘JA┘JA┘JA┘JA┘,╨ ж ,╨JA┘JA┘JA┘JA┘JA┘JA┘,╨ ,╨JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘ ж ,╨ФОъJA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘JA┘,╨ ,╨ФОъJA┘JA┘JA┘JA┘,╨,╨JA┘JA┘JA┘JA┘JA┘,╨ ,╨JA┘JA┘JA┘JA┘,╨ ,╨JA┘JA┘JA┘,╨ ж ,╨JA┘,╨ ж ,╨JA┘,╨ ж ж ж ,╨ ж ▄▄▄
|
||||
@@ -1,19 +0,0 @@
|
||||
<html><title>WebView Help</title><body>
|
||||
|
||||
<h1>WebView Text-Based Browser</h1>
|
||||
|
||||
It is free and open-source. If you have any suggestions or want to help improving it please visit its topic at <a href="//board.kolibrios.org/viewtopic.php?f=40&t=1075">board.kolibrios.org</a><pre>
|
||||
|
||||
<b>Shortcut keys</b>
|
||||
|
||||
<font bg=C7CEE4>[CTRL + N or CTRL + T]</font> New window
|
||||
<font bg=C7CEE4>[CTRL + R or F5]</font> Refresh the current page
|
||||
<font bg=C7CEE4>[CTRL + O]</font> Start OpenDialog to open local file
|
||||
<font bg=C7CEE4>[CTRL + U]</font> View a web page's source code
|
||||
<font bg=C7CEE4>[CTRL + H]</font> Open browser history
|
||||
<font bg=C7CEE4>[CTRL + J]</font> Display the file downloader
|
||||
<font bg=C7CEE4>[CTRL + W]</font> Exit browser
|
||||
<font bg=C7CEE4>[CTRL + ENTER]</font> Submit a web search
|
||||
<font bg=C7CEE4>[CTRL + LEFT]</font> Back a page.
|
||||
<font bg=C7CEE4>[CTRL + RIGHT]</font> Forward a page.
|
||||
<font bg=C7CEE4>[F6]</font> Moves a text cursor to the omnibox
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<meta charset="cp-866">
|
||||
<title>Справка WebView</title>
|
||||
<body><pre><h1>Справка WebView</h1>
|
||||
<b>Клавиши быстрого вызова</b>
|
||||
|
||||
<font bg=C7CEE4>[CTRL + N или CTRL + T]</font> Новое окно
|
||||
<font bg=C7CEE4>[CTRL + R или F5]</font> Перезагрузить страницу
|
||||
<font bg=C7CEE4>[CTRL + O]</font> Вызвать диалог выбора файла
|
||||
<font bg=C7CEE4>[CTRL + U]</font> Смотреть исходный код страницы
|
||||
<font bg=C7CEE4>[CTRL + H]</font> Смотреть историю посещенных страниц
|
||||
<font bg=C7CEE4>[CTRL + J]</font> Открыть загрузчик файлов
|
||||
<font bg=C7CEE4>[CTRL + W]</font> Закрыть браузер
|
||||
<font bg=C7CEE4>[CTRL + ENTER]</font> Поиск в интернете с помощью Google
|
||||
<font bg=C7CEE4>[CTRL + ВЛЕВО]</font> Аналогично кнопке "Назад" в браузере
|
||||
<font bg=C7CEE4>[CTRL + ВПРАВО]</font> Аналогично кнопке "Вперед"
|
||||
<font bg=C7CEE4>[F6]</font> Перемещает текстовый курсор в омнибокс
|
||||
@@ -1,121 +0,0 @@
|
||||
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, "<");
|
||||
new_buf+=4;
|
||||
continue;
|
||||
}
|
||||
if ('>' == ESBYTE[i]) {
|
||||
strcpy(new_buf, ">");
|
||||
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,49 +0,0 @@
|
||||
<html><head><title>New tab</title></head>
|
||||
<body bgcolor=#fff>
|
||||
|
||||
<table><tr><td width=20><td width=220><pre>
|
||||
_____________________
|
||||
|# : : #|
|
||||
| : WebView : |
|
||||
| : for : |
|
||||
| : KolibriOS : |
|
||||
| : : |
|
||||
| :_______________: |
|
||||
| ____________ |
|
||||
| | __ | |
|
||||
| || | | |
|
||||
\_____||__|________|__|<font color=#DDD>lc</font>
|
||||
|
||||
<font bg=#F8F15B> web <font bg=#FF5A7E color=#fff> 1.0 <font bg=#47D018> compatible
|
||||
<font bg=#3CE7FF> </font></font></font></font>
|
||||
<td>
|
||||
|
||||
</pre>
|
||||
<kosicon n=58><a href=//kolibrios.org>Homepage</a>
|
||||
<kosicon n=50><a href="//builds.kolibrios.org">Night-builds</a>
|
||||
<kosicon n=50><a href="//ftp.kolibrios.org">FTP Server</a>
|
||||
<pre>
|
||||
|
||||
By the way,
|
||||
<font color="#555555">• You can check for browser updates from the main menu.
|
||||
• To run a web search, type text in the address box and press Ctrl+Enter.
|
||||
• Pressing F6 moves the text cursor to the omnibox.
|
||||
• You can manually change the encoding of a page by clicking on the label in the bottom right corner.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~+
|
||||
|
||||
* +
|
||||
' |
|
||||
() .-.,="``"=. - o -
|
||||
'=/_ \ |
|
||||
* | '=.<a href=WebView:test> </a> |
|
||||
\ `=./`, '
|
||||
. '=.__.=' `=' *
|
||||
+ +
|
||||
O * ' .<font color=#DDD>jgs</font>
|
||||
@@ -1,49 +0,0 @@
|
||||
<html><head><title>Новая вкладка</title></head>
|
||||
<body bgcolor=#fff>
|
||||
|
||||
<table><tr><td width=20><td width=220><pre>
|
||||
_____________________
|
||||
|# : : #|
|
||||
| : WebView : |
|
||||
| : for : |
|
||||
| : KolibriOS : |
|
||||
| : : |
|
||||
| :_______________: |
|
||||
| ____________ |
|
||||
| | __ | |
|
||||
| || | | |
|
||||
\_____||__|________|__|<font color=#DDD>lc</font>
|
||||
|
||||
<font bg=#F8F15B> web <font bg=#FF5A7E color=#fff> 1.0 <font bg=#47D018> compatable
|
||||
<font bg=#3CE7FF> </font></font></font></font>
|
||||
<td>
|
||||
|
||||
</pre>
|
||||
<kosicon n=58><a href=//kolibrios.org>Официальный сайт</a>
|
||||
<kosicon n=50><a href="//builds.kolibrios.org">Ночные сборки</a>
|
||||
<kosicon n=50><a href="//ftp.kolibrios.org">FTP сервер</a>
|
||||
<pre>
|
||||
|
||||
Кстати,
|
||||
<font color="#555555">• Из главного меню можно проверить наличие обновлений
|
||||
• Для поиска в Google наберите тест в адресной строке и нажмите Ctrl+Enter
|
||||
• Клавиша F6 перемещает текстовый курсор в омнибокс.
|
||||
• Можно изменить кодировку страницы, для этого нажмите на надпись в правом нижнем углу окна.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~+
|
||||
|
||||
* +
|
||||
' |
|
||||
() .-.,="``"=. - o -
|
||||
'=/_ \ |
|
||||
* | '=.<a href=WebView:test> </a> |
|
||||
\ `=./`, '
|
||||
. '=.__.=' `=' *
|
||||
+ +
|
||||
O * ' .<font color=#DDD>jgs</font>
|
||||
@@ -1,14 +0,0 @@
|
||||
<html>
|
||||
<head><title>Page not found</title></head>
|
||||
<body>
|
||||
<h1> Webpage Not Available</h1>
|
||||
<h2> What could be done:</h2>
|
||||
<ul>
|
||||
<li>Make sure that you have a working Internet connection.<br>
|
||||
Open <a href="/sys/network/netcfg">Netcfg</a> network diagnostic tool.<br>
|
||||
<li>Check the page address for any typos.<br>
|
||||
<li>Server is temporarily unavailable.<br>
|
||||
Refresh the page.<br>
|
||||
<li>Browser didn't properly handle the server's response.<br>
|
||||
Please, report an error.<br>
|
||||
</ul>
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="cp-866">
|
||||
<title>Страница не найдена</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Веб-страница недоступна <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAdCAMAAAD8QJ61AAAAIVBMVEUBAAAAAAAAgAAAgIAAAIAAAP+AgICZmZnAwMD/mZn///8vq9FJAAAAAXRSTlMAQObYZgAAAORJREFUeNpiGHQAUCcZoEgMwzAQyXbj9f8ffMJp7xz2Om2dgAaUQLF5j8vKBPAS5xWk6eM/iuKqcD7gK6+rjMEXAwqvkX61ICuSwo2uR5jjKBBkCA1ZJDiFrEqahzMIaAgnMG9AjwyBtdAVdO1uwVSQln0GCQvdsU4hkg2WgFhDSBl5DaEZgmVF1ZlPA2kxG0pjL4/QxnWZbQE9ekHHWJHRUMLns260ldA27RCw+m1BGwg+wu5odsM9LYZx3gF7hocwCYFfjr9Vhh5juBb3EQp0rYKgN91/Cu34iGdBHwT729V/8Q+bbAkSfuA/hwAAAABJRU5ErkJggg=="></h1>
|
||||
|
||||
<ul>
|
||||
<li>Проверьте адресс страницы, возможно, была сделана опечатка.<br>
|
||||
<li>Сервер временно недоступен. Штош поделать...<br>
|
||||
<li>Убедитесь, что есть подключение к сети Интернет.<br>
|
||||
В Колибри поддерживается только подключение по кабелю (WiFi не работает). Если кабель подключен, проверьте установлен ли драйвер сетевой карты. Для этого откройте <a href="/sys/network/netcfg">Netcfg</a> и убедитесь, что в колонке DRIVER указано имя двайвера.<br>
|
||||
Список поддерживаемых сетевых карт <a target="_blank" href="/kolibrios/res/guide/hardware_support.htm#net">тут</a>.<br>
|
||||
<li>Текстовый браузер не правильно обработал ответ сервера.<br>
|
||||
Сообщите об ошибке.<br>
|
||||
</ul>
|
||||
@@ -1,39 +0,0 @@
|
||||
<html>
|
||||
<title>TEST</title>
|
||||
<body bgcolor=#fff>
|
||||
|
||||
<pre><h3><kosicon n=21>Tables</h3>
|
||||
<a href=//th99.infania.net>Total Hardware 1999</a>
|
||||
<a href=//xcal1.vodafone.co.uk>Vodafone Test Files</a>
|
||||
<a href=//vetusware.com>vetusware.com</a>
|
||||
<a href=//toastytech.com/guis/index.html>GUI Gallery</a>
|
||||
<a href=//www.weitek.com/textual/support/driver.html>weitek</a>
|
||||
<a href=http://www.retro-computing.com/Home/retro-computing.php>retro-computing</a>
|
||||
<a href=https://www.alanwood.net/unicode/cyrillic.html>cyrillic</a>
|
||||
|
||||
<pre><h3><kosicon n=22>Demoscene</h3>
|
||||
<a href="https://amp.dascene.net/home.php">Amiga Music Preservation</a>
|
||||
<a href="https://files.scene.org">Scene.org</a>
|
||||
<a href=https://www.pouet.net/>Pouet.net</a>
|
||||
<a href="https://aminet.net/tree?path=mods">Aminet</a>
|
||||
<a href=https://barefeats.com/indarch.html>barefeats</a>
|
||||
|
||||
<h3><kosicon n=13>Forms</h3>
|
||||
<a href=//wiby.org>wiby.org</a>
|
||||
|
||||
|
||||
<h3><kosicon n=3>Other</h3>
|
||||
<a href=//menuetos.net>menuetos.net</a>
|
||||
<a href=//osnews.com>osnews.com</a>
|
||||
|
||||
|
||||
<h3><kosicon n=54>Cyrillic only</h3>
|
||||
<a href=//dgmag.in>dgmag.in</a> <a href=//old-dos.ru>old-dos.ru</a> <a href=//lionovsky.us>lionovsky.us</a> <a href=//mirrors.pdp-11.ru>mirrors.pdp-11.ru</a>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
qemu-system-i386 -m 512 -fda kolibri.img -boot a -vga vmware -net nic,model=rtl8139 -net user -soundhw ac97 -usb -usbdevice tablet -enable-kvm -drive file=fat:rw:.
|
||||
@@ -1,10 +0,0 @@
|
||||
_ini ini;
|
||||
|
||||
void LoadIniConfig()
|
||||
{
|
||||
ini.path = GetIni(#settings_file, "app.ini");
|
||||
ini.section = "WebView";
|
||||
|
||||
ini.GetString("proxy_address", #proxy_address, sizeof(proxy_address), NULL);
|
||||
ini.GetString("search_engine", #search_engine, sizeof(search_engine), "http://bing.com/search?q=");
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
enum { TAG=1, VALUE, TEXT, COMMENT, SCRIPT};
|
||||
|
||||
int opened_font_counter=0;
|
||||
int mode;
|
||||
|
||||
dword source_buf_end;
|
||||
|
||||
void SourceBufAdd(dword _mode, src)
|
||||
{
|
||||
dword font_found_pointer, src_orig = src;
|
||||
|
||||
if (_mode) mode = _mode;
|
||||
|
||||
strcpy(source_buf_end, src);
|
||||
source_buf_end += strlen(source_buf_end);
|
||||
|
||||
if (font_found_pointer = strstr(src, "</font>")) {
|
||||
opened_font_counter--;
|
||||
}
|
||||
|
||||
if (font_found_pointer = strstr(src_orig, "<font ")) {
|
||||
opened_font_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
void CloseAllOpenedFonts(dword _mode)
|
||||
{
|
||||
while (opened_font_counter) SourceBufAdd(_mode, "</font>");
|
||||
}
|
||||
|
||||
dword ShowSource(dword _bufdata, _in_bufsize)
|
||||
{
|
||||
dword i, j;
|
||||
bool activate_script_mode = false;
|
||||
dword source_buf_start;
|
||||
|
||||
opened_font_counter=0;
|
||||
source_buf_start = malloc(_in_bufsize*5);
|
||||
source_buf_end = source_buf_start;
|
||||
|
||||
SourceBufAdd(TEXT, "<html><head><title>View Source</title><body><pre>");
|
||||
|
||||
for (i=_bufdata; i<_bufdata+_in_bufsize; i++) switch (ESBYTE[i])
|
||||
{
|
||||
case '<':
|
||||
if (!strncmp(i+1,"!--", 3)) SourceBufAdd(COMMENT, "<font color=#bbb><");
|
||||
else if (SCRIPT == mode) {
|
||||
if (!strncmp(i+1,"/script>", 8)) {
|
||||
CloseAllOpenedFonts(NULL);
|
||||
SourceBufAdd(TAG, "<font color=#00f><");
|
||||
}
|
||||
else SourceBufAdd(NULL, "<");
|
||||
}
|
||||
else if (COMMENT == mode) {
|
||||
SourceBufAdd(NULL, "<");
|
||||
}
|
||||
else if (TEXT == mode) {
|
||||
if (!strncmp(i+1,"script", 6)) activate_script_mode = true;
|
||||
SourceBufAdd(TAG, "<font color=#00f><");
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (TAG == mode) && (activate_script_mode) {
|
||||
activate_script_mode = false;
|
||||
SourceBufAdd(SCRIPT, "></font><font color=#994500>");
|
||||
}
|
||||
else if (VALUE == mode) CloseAllOpenedFonts(TEXT);
|
||||
else if (COMMENT == mode) && (!strncmp(i-2,"--", 2)) {
|
||||
SourceBufAdd(TEXT, ">");
|
||||
CloseAllOpenedFonts(TEXT);
|
||||
}
|
||||
else if (COMMENT == mode) || (SCRIPT == mode) SourceBufAdd(NULL, ">");
|
||||
else if (TAG == mode) SourceBufAdd(TEXT, "></font>");
|
||||
break;
|
||||
case '&':
|
||||
SourceBufAdd(NULL, "&");
|
||||
break;
|
||||
case '\"':
|
||||
case '\'':
|
||||
if (TAG == mode) SourceBufAdd(VALUE, "<font color=#F301F2>"");
|
||||
else if (VALUE == mode) SourceBufAdd(TAG, ""</font>");
|
||||
else SourceBufAdd(NULL, """);
|
||||
break;
|
||||
default:
|
||||
ESBYTE[source_buf_end] = ESBYTE[i];
|
||||
source_buf_end++;
|
||||
}
|
||||
ESBYTE[source_buf_end] = 0;
|
||||
LoadInternalPage(source_buf_start, source_buf_end-source_buf_start);
|
||||
free(source_buf_start);
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// MODULE //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
#define TABS_MAX 5
|
||||
|
||||
TWebBrowser tabdata[TABS_MAX+1];
|
||||
_history tabstory[TABS_MAX+1];
|
||||
|
||||
struct TAB
|
||||
{
|
||||
int count;
|
||||
signed int active;
|
||||
bool add();
|
||||
bool close();
|
||||
void save_state();
|
||||
void restore();
|
||||
} tab = {1,0};
|
||||
|
||||
|
||||
bool TAB::add()
|
||||
{
|
||||
if (count==TABS_MAX) return false;
|
||||
save_state();
|
||||
count++;
|
||||
active = count-1;
|
||||
history = tabstory[active];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TAB::close(int _tab_number)
|
||||
{
|
||||
int i;
|
||||
if (count==1) return false;
|
||||
for (i=_tab_number; i<TABS_MAX; i++) {
|
||||
tabdata[i] = tabdata[i+1];
|
||||
tabstory[i] = tabstory[i+1];
|
||||
}
|
||||
if (_tab_number<active) && (active>0) active--;
|
||||
if (active==count-1) && (active>0) active--;
|
||||
count--;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TAB::save_state()
|
||||
{
|
||||
tabstory[active] = history;
|
||||
tabdata[active] = WB1;
|
||||
}
|
||||
|
||||
void TAB::restore(int _id)
|
||||
{
|
||||
tab.active = _id;
|
||||
WB1 = tabdata[_id];
|
||||
history = tabstory[_id];
|
||||
}
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// WebView Actions //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
#define DEFAULT_TABW 220
|
||||
int tab_w = DEFAULT_TABW;
|
||||
|
||||
int GetTabWidth()
|
||||
{
|
||||
if (tab.count == TABS_MAX) return Form.cwidth / tab.count;
|
||||
if (tab.count * DEFAULT_TABW + TAB_H < Form.cwidth) return DEFAULT_TABW; else
|
||||
return Form.cwidth - TAB_H - 2 / tab.count;
|
||||
}
|
||||
|
||||
void DrawTab(int _id)
|
||||
{
|
||||
#define CLOSE_S 13
|
||||
dword bgcol, border_bottom_color;
|
||||
char header_no_version[sizeof(TWebBrowser.header)];
|
||||
char name[DEFAULT_TABW/6];
|
||||
int xxx = _id * tab_w;
|
||||
|
||||
if (_id==tab.active) {
|
||||
tab.save_state();
|
||||
bgcol = sc.light;
|
||||
border_bottom_color = sc.light;
|
||||
} else {
|
||||
bgcol=sc.work;
|
||||
border_bottom_color = sc.line;
|
||||
}
|
||||
if (tabdata[_id].header) {
|
||||
strncpy(#header_no_version, #tabdata[_id].header, strlen(#tabdata[_id].header)-sizeof(version)-2);
|
||||
strncpy(#name, #header_no_version, tab_w-CLOSE_S/6-2);
|
||||
}
|
||||
DrawBar(xxx, TOOLBAR_H, 1, TAB_H, sc.dark);
|
||||
DrawBar(xxx+1, TOOLBAR_H, tab_w-1, TAB_H-1, bgcol);
|
||||
DrawBar(xxx+1, TOOLBAR_H+TAB_H-1, tab_w-1, 1, border_bottom_color);
|
||||
DefineHiddenButton(xxx, TOOLBAR_H-1, tab_w, TAB_H, TAB_ID+_id);
|
||||
WriteTextCenter(xxx, TOOLBAR_H+6, tab_w-CLOSE_S, sc.work_text, #name);
|
||||
|
||||
DefineHiddenButton(xxx+tab_w-CLOSE_S-3, TOOLBAR_H+3, CLOSE_S-1, CLOSE_S-1, TAB_CLOSE_ID+_id);
|
||||
DrawBar(xxx+tab_w-CLOSE_S-3, TOOLBAR_H+3, CLOSE_S, CLOSE_S, sc.dark);
|
||||
WriteText(xxx+tab_w-CLOSE_S+1, TOOLBAR_H+5, 0x80, sc.light, "x");
|
||||
}
|
||||
|
||||
void DrawActiveTab()
|
||||
{
|
||||
if (tab_w == GetTabWidth()) DrawTab(tab.active);
|
||||
else DrawTabsBar();
|
||||
}
|
||||
|
||||
int DrawNewTabButton()
|
||||
{
|
||||
dword btn_light = MixColors(sc.button, 0xFFFfff, 220);
|
||||
dword btn_dark = MixColors(sc.button, 0, 180);
|
||||
int xxx = tab.count * tab_w;
|
||||
|
||||
if (tab.count < TABS_MAX) {
|
||||
DrawBar(xxx, TOOLBAR_H, 1, TAB_H, sc.line);
|
||||
DrawBar(xxx+1, TOOLBAR_H, TAB_H, TAB_H-1, sc.button);
|
||||
DrawRectangle3D(xxx+1, TOOLBAR_H, TAB_H, TAB_H-1, btn_light, btn_dark);
|
||||
PutPixel(xxx+1+TAB_H, TOOLBAR_H, btn_dark);
|
||||
DefineHiddenButton(xxx+1, TOOLBAR_H, TAB_H-1, TAB_H-1, NEW_TAB);
|
||||
WriteText(xxx+7, TOOLBAR_H+2, 0x90, sc.button_text, "+");
|
||||
return xxx + TAB_H + 2;
|
||||
} else {
|
||||
return xxx;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTabsBar()
|
||||
{
|
||||
dword i;
|
||||
tab_w = GetTabWidth();
|
||||
for (i=0; i<tab.count; i++) DrawTab(i);
|
||||
i = DrawNewTabButton();
|
||||
DrawBar(i, TOOLBAR_H, Form.cwidth-i, TAB_H-1, MixColors(sc.dark, sc.work, 128));
|
||||
DrawBar(i, TOOLBAR_H+TAB_H-1, Form.cwidth-i, 1, sc.line);
|
||||
}
|
||||
|
||||
void EventTabClose(int _id)
|
||||
{
|
||||
DeleteButton(TAB_ID + tab.count-1);
|
||||
if (_id == tab.active) {
|
||||
tab.close(_id);
|
||||
tab.restore(tab.active);
|
||||
SetElementSizes();
|
||||
WB1.Reparse();
|
||||
WB1.DrawPage();
|
||||
SetOmniboxText(history.current());
|
||||
} else {
|
||||
tab.close(_id);
|
||||
}
|
||||
DrawTabsBar();
|
||||
DrawStatusBar(NULL);
|
||||
}
|
||||
|
||||
void EventCloseActiveTab()
|
||||
{
|
||||
EventTabClose(tab.active);
|
||||
}
|
||||
|
||||
void EventTabClick(int _id)
|
||||
{
|
||||
if (_id>=tab.count) _id = 0;
|
||||
if (_id==-1) _id = tab.count-1;
|
||||
tab.save_state();
|
||||
tab.restore(_id);
|
||||
DrawTabsBar();
|
||||
SetElementSizes();
|
||||
WB1.Reparse();
|
||||
WB1.DrawPage();
|
||||
SetOmniboxText(history.current());
|
||||
DrawStatusBar(NULL);
|
||||
}
|
||||
|
||||
void EventOpenNewTab(dword _url)
|
||||
{
|
||||
tab.add();
|
||||
OpenPage(_url);
|
||||
DrawTabsBar();
|
||||
}
|
||||
|
||||
void EventActivateNextTab()
|
||||
{
|
||||
EventTabClick(tab.active+1);
|
||||
}
|
||||
|
||||
void EventActivatePreviousTab()
|
||||
{
|
||||
EventTabClick(tab.active-1);
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<!--doctype html public "-//w3c//dtd html 4.0 transitional//ru"-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Тест Acid 0.1</title>
|
||||
</head>
|
||||
<body bgcolor="#000000" link="#0066FF" text="#FFFFFF">
|
||||
<h1 align=center>Тест Acid 0.1</h1>
|
||||
<br>
|
||||
<b>Это тестовая страница для проверки текстового браузера <s>HTML Viewer</s> WebView</b>
|
||||
|
||||
<p>Из кодировок поддерживаются: CP866(DOS), CP1251(Windows), CP1252(Latin legacy), KOI8, и конечно UTF8. CSS и Javascript пока не реализованы (ахахаха). Поддержка тега <table> крайне базовая, поддержки вложенных таблиц нет.
|
||||
</p>
|
||||
|
||||
<h3>История</h3>
|
||||
|
||||
Ранее программа называлась <b >HTMLv (HTML Viewer)</b> и изначально задумывалась как <q>Центр справки и поддержки</q>. Чтобы не изобретать велосипед и одновременно исполнить мечту многих, форматом просматриваемых страниц был выбран html.
|
||||
Первоначальный автор Veliant, затем разработка была подхвачена дизайнером Leency. Это была моя вторая программа после файлового менеджера Eolite.<br>
|
||||
|
||||
<span> <br />
|
||||
|
||||
<b>
|
||||
<font color="#FF0000">K</font>
|
||||
<font color="#FFC005">o</font>
|
||||
<font color="#F6F574">l</font>
|
||||
<font color="#9EFC36">i</font>
|
||||
<font color="#29FDFD">b</font>
|
||||
<font color="#36A8FC">r</font>
|
||||
<font color="blueviolet">i</font>
|
||||
<font color="#C911FF">O</font>
|
||||
<font color="#C911FF">S</font>
|
||||
|
||||
<font color="#C911FF">F</font>
|
||||
<font color="#36A8FC">o</font>
|
||||
<font color="#29FDFD">r</font>
|
||||
<font color="#9EFC36">e</font>
|
||||
<font color="#FFC005">v</font>
|
||||
<font color="#FF0000">e</font>
|
||||
<font color="#FFC005">r</font>
|
||||
</b>
|
||||
<br>
|
||||
|
||||
<table>
|
||||
<td>
|
||||
<bg bgcolor=#333>
|
||||
Небольшой список:<ol>
|
||||
<li><q>Этот текст в кавычках</q></li>
|
||||
<li><u>Это подчеркнутый текст</u></li>
|
||||
<li><s>Это перечеркнутый текст</s></li>
|
||||
<li><i>Это наклонный текст</i></li>
|
||||
<li><strong>Это текст с усиленным выделением</strong></li>
|
||||
<li><b><u><s><font color="#777444">Много тегов</font></s></u></b></ol>
|
||||
</bg>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
<!-- комментарий: этого текста здесь <нет> -->
|
||||
|
||||
<br>
|
||||
|
||||
<img alt="нет картинки, просто alt">
|
||||
|
||||
<img src = http://wiby.org/about/wibyplex.gif>
|
||||
|
||||
<a href="http://kolibrios.org/i/logo.png"><img id="2.1.4" src="http://kolibrios.org/i/logo.png" alt="logo"><br>Открыть</a><br>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<a href='./index.htm'>./index.htm</a><br>
|
||||
<a href='/sys/index.htm'>Незакрытый тег а - index.htm<br>
|
||||
<a href="/sys/calc">/sys/calc</a><br>
|
||||
<a href="#2.1.4">#2.1.4</a><br>
|
||||
<a href="http://kolibrios.org">http://kolibrios.org</a><br>
|
||||
<a href="mailto:leency@mail.ru">Mail to Leency</a><br>
|
||||
<br>
|
||||
|
||||
<h1><a href=#>Link H1</a> <u>Underline H1</u></h1>
|
||||
<h2><a href=#>Link H2</a> <u>Underline H2</u></h2>
|
||||
<h3><a href=#>Link H3</a> <u>Underline H2</u></h3>
|
||||
<a href=#>Link</a> <u>Underline</u>
|
||||
|
||||
<td>
|
||||
|
||||
<pre>
|
||||
"Осень уже пришла!"-
|
||||
Шепнул мне на ухо ветер,
|
||||
Подкравшись к подушке моей.
|
||||
|
||||
Басе
|
||||
|
||||
</pre><br>
|
||||
|
||||
В этом тексте есть переход на следующую строку, но браузер
|
||||
его должен проигнорировать. Еще много пробелов. А тут есть
|
||||
табы. Кое-какие символы: " & < > •
|
||||
© ® „ “ — Їжачок іншого боку р. Євфрат з'їв ґрунт та єврейський ґербалайф.
|
||||
|
||||
<p>61055, г.
|
||||
Харьков, ул. Краснознаменная, 16</SPAN>, радиофизический
|
||||
корпус на территории НТУ «ХПИ»
|
||||
</p>
|
||||
|
||||
<pre><font color="#000">
|
||||
<font bg=#FFED00 style="background-color:#FFED00"> Заметки </font>
|
||||
<font bg=#FFFBCE style="background-color:#FFFBCE"> </font>
|
||||
<font bg=#FFFBCE style="background-color:#FFFBCE"> Речка на Жукова </font>
|
||||
<font bg=#FFFBCE style="background-color:#FFFBCE"> Heroes 3 </font>
|
||||
<font bg=#FFFBCE style="background-color:#FFFBCE"> Рисостерон, куринабол </font>
|
||||
<font bg=#FFFBCE style="background-color:#FFFBCE"> </font>
|
||||
</font></pre>
|
||||
|
||||
</table>
|
||||
|
||||
<hr color="#758999">
|
||||
<center>Zhytomyr 2008-2025</center>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,36 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<form action="https://www.w3schools.com/action_page.php">
|
||||
First name: <input type="text" name="fname" value="Mickey"><br>
|
||||
Last name: <input type="text" name="lname" value="Mouse"><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<form action="https://www.w3schools.com/action_page.php" method="post">
|
||||
First name: <input type="text" name="fname" value="Aboba"><br>
|
||||
Last name: <input type="text" name="lname" value="Aboba"><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<p>Click the "Submit" button and the form-data will be sent to a script on the server.</p>
|
||||
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
<h1>aboba</h1><br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,12 +0,0 @@
|
||||
; ┬ ¤Єюь Їрщых ьюцэю шчьхэшЄ№ эрёЄЁющъш ъюьяшы ЄюЁр яю єьюыўрэш■.
|
||||
J0 ; эх фхырЄ№ эрўры№э√щ jump эр main()
|
||||
r- ; чряЁхЄшЄ№ шчьхэхэшх фюёЄєяэющ ярь Єш т *.com Їрщырї
|
||||
X ; чряЁхЄшЄ№ тъы■ўхэшх т т√їюфэющ Їрщы эрфяшёш SPHINXC--
|
||||
4 ; ъюьяшышЁютрЄ№ ъюф фы 80386 яЁюЎхёёюЁр
|
||||
oc ; юяЁшьшчрЎш яю ЁрчьхЁє ъюфр
|
||||
w ; т√фртрЄ№ яЁхфєяЁхцфхэш
|
||||
de ; шёяюы№чютрЄ№ тЁхьхээюх Ёрё°шЁхэшх Єшяр яЁш фхыхэшш
|
||||
ON ; тъы■ўшЄ№ юяЄшьшчрЎш■ ўшёхы
|
||||
ost ; юяЄшьшчшЁютрЄ№ ЄхъёЄют√х ъюэёЄрэЄ√
|
||||
;dos4gw
|
||||
;env
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("clipview.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "clipview.com")
|
||||
@@ -1,5 +0,0 @@
|
||||
@del clipview
|
||||
@c-- /D=LANG_ENG clipview.c
|
||||
@rename clipview.com clipview
|
||||
@del warning.txt
|
||||
@pause
|
||||
@@ -1,30 +0,0 @@
|
||||
Содержимое контейнера буфера обмена
|
||||
|
||||
1. Первый dword содержит общую длину данных в контейнере
|
||||
|
||||
2. Второй dword указывает тип данныx:
|
||||
0 = Текст
|
||||
1 = Изображение
|
||||
2 = RAW
|
||||
4 и выше зарезервировано
|
||||
|
||||
2.1 Текст
|
||||
Данные в третьем dword содержат тип кодировки:
|
||||
0 = UTF
|
||||
1 = 0866
|
||||
2 = 1251
|
||||
3 и выше зарезервировано
|
||||
|
||||
2.2 Изображение
|
||||
Третий dword - размер по X
|
||||
Четвертый dword - размер по Y
|
||||
Пятый dword - глубина цвета в битах (8, 16, 24, 32, 48, 64)
|
||||
Шестой dword - Указатель на палитру (смещение от начала файла).
|
||||
Если палитры нет то значение 0
|
||||
Седьмой dword - Размер области палитры, максимальное значение 256*4=1024байт.
|
||||
Если палитры нет то значение 0
|
||||
Восьмой dword - Указатель на данные пикселей для R, G, B.
|
||||
Девятый dword - Размер области данных для пикселей.
|
||||
|
||||
2.3 RAW
|
||||
Может содержать любые данные, т.к. содержимое на усмотрение программиста
|
||||
@@ -1,268 +0,0 @@
|
||||
#define ENTRY_POINT #main
|
||||
|
||||
#define MEMSIZE 4096*20
|
||||
|
||||
#include "..\lib\strings.h"
|
||||
#include "..\lib\clipboard.h"
|
||||
#include "..\lib\gui.h"
|
||||
#include "..\lib\fs.h"
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// DATA //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
?define T_COLUMNS_TITLE "# Size Type Contents"
|
||||
?define DEFAULT_SAVE_PATH "/tmp0/1/clipview.tmp"
|
||||
char *data_type[] = { "Text", "Image", "RAW", "Unknown" };
|
||||
|
||||
enum {
|
||||
BT_DELETE_LAST = 10,
|
||||
BT_DELETE_ALL,
|
||||
BT_UNLOCK,
|
||||
BT_LIST_LEFT,
|
||||
BT_LIST_RIGHT
|
||||
};
|
||||
|
||||
#define PANEL_BOTTOM_H 35
|
||||
#define GAP 5
|
||||
#define LIST_Y 32
|
||||
#define PANEL_TOP_H LIST_Y-2
|
||||
#define LINE_H 20
|
||||
#define TEXT_Y LINE_H - 14 / 2
|
||||
|
||||
proc_info Form;
|
||||
|
||||
struct LIST {
|
||||
int w,h;
|
||||
int count;
|
||||
int first;
|
||||
int visible;
|
||||
} list = 0;
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// CODE //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void main()
|
||||
{
|
||||
@mem_init();
|
||||
@SetEventMask(EVM_REDRAW + EVM_BUTTON);
|
||||
loop() switch(@WaitEventTimeout(10))
|
||||
{
|
||||
case evButton:
|
||||
@GetButtonID();
|
||||
switch(EAX) {
|
||||
case 1:
|
||||
ExitProcess();
|
||||
case BT_DELETE_LAST:
|
||||
EventDeleteLastSlot();
|
||||
break;
|
||||
case BT_DELETE_ALL:
|
||||
EventDeleteAllSlots();
|
||||
break;
|
||||
case BT_UNLOCK:
|
||||
EventResetBufferLock();
|
||||
break;
|
||||
case BT_LIST_LEFT:
|
||||
list.first -= list.visible;
|
||||
if (list.first <= 0) list.first = 0;
|
||||
ClipViewSelectListDraw();
|
||||
break;
|
||||
case BT_LIST_RIGHT:
|
||||
if (list.first + list.visible < list.count) list.first += list.visible;
|
||||
ClipViewSelectListDraw();
|
||||
break;
|
||||
default:
|
||||
if (EAX>=300) EventOpenAsHex(EAX-300);
|
||||
else EventOpenAsText(EAX-100);
|
||||
}
|
||||
break;
|
||||
|
||||
case evReDraw:
|
||||
sc.get();
|
||||
DefineAndDrawWindow(GetScreenWidth()-600/2,80,600,400,0x73,NULL,"Clipboard Viewer",NULL);
|
||||
GetProcessInfo(#Form, SelfInfo);
|
||||
IF (Form.status_window&ROLLED_UP) break;
|
||||
IF (Form.height < 200) { MoveSize(OLD,OLD,OLD,200); break; }
|
||||
IF (Form.width < 570) { MoveSize(OLD,OLD,570,OLD); break; }
|
||||
DrawWindowContent();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Clipboard__GetSlotCount() > list.count) ClipViewSelectListDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWindowContent()
|
||||
{
|
||||
list.w = Form.cwidth-GAP-GAP;
|
||||
list.h = Form.cheight-PANEL_BOTTOM_H-LIST_Y-GAP;
|
||||
list.visible = list.h / LINE_H;
|
||||
|
||||
DrawBar(0,0, Form.cwidth, PANEL_TOP_H, sc.work);
|
||||
DrawBar(0,Form.cheight-PANEL_BOTTOM_H, Form.cwidth, PANEL_BOTTOM_H, sc.work);
|
||||
DrawWideRectangle(GAP-GAP, LIST_Y-GAP, GAP*2+list.w, GAP*2+list.h, GAP-2, sc.work);
|
||||
|
||||
DefineButton(GAP, list.h + LIST_Y + 8, 110, 25, BT_DELETE_LAST, sc.button);
|
||||
$inc edx
|
||||
$add ebx, 130 << 16 //BT_DELETE_ALL
|
||||
$int 64
|
||||
$inc edx
|
||||
$add ebx, 130 << 16 //BT_UNLOCK
|
||||
$int 64
|
||||
|
||||
WriteText(GAP+11, LIST_Y + list.h + 14, 0x90, sc.button_text, "Delete last Delete all Reset lock");
|
||||
|
||||
WriteText(GAP+18, LIST_Y - 23, 0x90, sc.work_text, T_COLUMNS_TITLE);
|
||||
ClipViewSelectListDraw();
|
||||
SelectList_DrawBorder();
|
||||
}
|
||||
|
||||
dword slot_data;
|
||||
struct clipboard_data
|
||||
{
|
||||
dword size;
|
||||
dword type;
|
||||
dword encoding;
|
||||
dword content;
|
||||
dword content_offset;
|
||||
} cdata;
|
||||
|
||||
void SelectList_DrawLine(dword i)
|
||||
{
|
||||
int yyy, slot_data_type_number;
|
||||
|
||||
yyy = i*LINE_H+LIST_Y;
|
||||
DrawBar(GAP, yyy, list.w, LINE_H, -i%2 * 0x0E0E0E + 0xF1F1f1);
|
||||
|
||||
if (list.first + i >= list.count) {
|
||||
return;
|
||||
}
|
||||
|
||||
slot_data = Clipboard__GetSlotData(list.first + i);
|
||||
cdata.size = ESDWORD[slot_data];
|
||||
cdata.type = ESDWORD[slot_data+4];
|
||||
if (cdata.type==SLOT_DATA_TYPE_TEXT) || (cdata.type==SLOT_DATA_TYPE_TEXT_BLOCK)
|
||||
cdata.content_offset = 12;
|
||||
else
|
||||
cdata.content_offset = 8;
|
||||
cdata.content = slot_data + cdata.content_offset;
|
||||
|
||||
WriteText(list.first+i/10^1*8+GAP+12, yyy+TEXT_Y, 0x90, 0x000000, itoa(list.first + i));
|
||||
EDX = ConvertSizeToKb(cdata.size);
|
||||
WriteText(GAP+44+16, yyy+TEXT_Y, 0x90, 0x000000, EDX);
|
||||
slot_data_type_number = cdata.type;
|
||||
if (slot_data_type_number >= 4) slot_data_type_number = 3;
|
||||
WriteText(GAP+140, yyy+TEXT_Y, 0x90, 0x000000, data_type[slot_data_type_number]);
|
||||
WriteTextB(GAP+list.w - 88, yyy+TEXT_Y, 0x90, 0x006597, "TEXT HEX");
|
||||
DefineButton(GAP+list.w - 98, yyy, 50, LINE_H, 100+i+BT_HIDE, NULL);
|
||||
$add edx, 200
|
||||
$add ebx, 52 << 16 - 10 //BT_HEX
|
||||
$int 64
|
||||
|
||||
ESI = list.w - 345 / 8;
|
||||
if (cdata.size - cdata.content_offset < ESI) ESI = cdata.size - cdata.content_offset;
|
||||
WriteText(GAP+236, yyy+TEXT_Y, 0x30, 0x000000, cdata.content);
|
||||
}
|
||||
|
||||
int SaveSlotContents() {
|
||||
if (! CreateFile(cdata.size, cdata.content, DEFAULT_SAVE_PATH)) {
|
||||
return true;
|
||||
} else {
|
||||
notify("'Can not create /tmp0/1/clipview.tmp' -E");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ClipViewSelectListDraw()
|
||||
{
|
||||
int i, list_last;
|
||||
|
||||
list.count = Clipboard__GetSlotCount();
|
||||
if (list.first >= list.count) list.first = list.count - list.visible;
|
||||
if (list.first < 0) list.first = 0;
|
||||
|
||||
if (list.count > list.visible) list_last = list.visible; else list_last = list.count;
|
||||
|
||||
for (i=0; i<list_last; i++;) SelectList_DrawLine(i);
|
||||
|
||||
DrawBar(GAP,i*LINE_H+LIST_Y, list.w, -i*LINE_H+ list.h, 0xFFFfff);
|
||||
if (!list.count) WriteText(list.w / 2 + GAP - 60,
|
||||
list.h / 2 - 8 + LIST_Y, 0x90, 0x999999, "No data to show");
|
||||
|
||||
//Show "<" and ">" buttons and a page number
|
||||
//in case when there are items more than visible at once
|
||||
if (list.count > list.visible) {
|
||||
param[0] = list.first / list.visible + '0';
|
||||
param[1] = '\0';
|
||||
DefineButton(Form.cwidth-84-GAP, list.h + LIST_Y + 8, 25, 25, BT_LIST_LEFT, sc.button); //BT_LEFT
|
||||
$inc edx
|
||||
$add ebx, 57 << 16 //BT_RIGHT
|
||||
$int 64
|
||||
WriteText(Form.cwidth-84-GAP+10, list.h + LIST_Y + 14, 0x90, sc.button_text, "< >");
|
||||
$add ebx, 28 << 16
|
||||
$mov edx, #param;
|
||||
$mov edi, sc.work
|
||||
$mov ecx, 11010000b << 24
|
||||
$add ecx, sc.work_text //page number
|
||||
$int 64
|
||||
}
|
||||
}
|
||||
|
||||
void SelectList_DrawBorder() {
|
||||
DrawRectangle3D(GAP-2, LIST_Y-2,
|
||||
list.w+3, list.h+3,
|
||||
sc.dark, sc.light);
|
||||
DrawRectangle3D(GAP-1, LIST_Y-1,
|
||||
list.w+1, list.h+1,
|
||||
sc.line, sc.line);
|
||||
}
|
||||
|
||||
//===================================================//
|
||||
// //
|
||||
// EVENTS //
|
||||
// //
|
||||
//===================================================//
|
||||
|
||||
void EventDeleteLastSlot()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<list.visible; i++;) {
|
||||
DeleteButton(list.first + i + 100);
|
||||
$add edx, 200
|
||||
$int 64
|
||||
}
|
||||
Clipboard__DeleteLastSlot();
|
||||
DrawWindowContent();
|
||||
}
|
||||
|
||||
void EventDeleteAllSlots()
|
||||
{
|
||||
while (Clipboard__GetSlotCount()) Clipboard__DeleteLastSlot();
|
||||
DrawWindowContent();
|
||||
}
|
||||
|
||||
void EventResetBufferLock() {
|
||||
Clipboard__ResetBlockingBuffer();
|
||||
DrawWindowContent();
|
||||
}
|
||||
|
||||
void EventOpenAsText(int slot_id) {
|
||||
slot_data = Clipboard__GetSlotData(slot_id);
|
||||
cdata.size = ESDWORD[slot_data]-12;
|
||||
cdata.content = slot_data+12;
|
||||
if (SaveSlotContents()) RunProgram("/sys/develop/cedit", DEFAULT_SAVE_PATH);
|
||||
}
|
||||
|
||||
void EventOpenAsHex(int slot_id) {
|
||||
slot_data = Clipboard__GetSlotData(slot_id);
|
||||
cdata.size = ESDWORD[slot_data];
|
||||
cdata.content = slot_data;
|
||||
if (SaveSlotContents()) RunProgram("/sys/develop/heed", DEFAULT_SAVE_PATH);
|
||||
}
|
||||
|
||||
stop:
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("dicty.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "dicty.com")
|
||||
@@ -1,5 +0,0 @@
|
||||
@c-- /D=LANG_ENG dicty.c
|
||||
@del dicty
|
||||
@rename dicty.com dicty
|
||||
@del warning.txt
|
||||
@pause
|
||||
@@ -1,5 +0,0 @@
|
||||
@c-- /D=LANG_RUS dicty.c
|
||||
@del dicty
|
||||
@rename dicty.com dicty
|
||||
@del warning.txt
|
||||
@pause
|
||||
@@ -1,205 +0,0 @@
|
||||
#define MEMSIZE 4096 * 1024 * 2
|
||||
#define NO_DLL_INIT
|
||||
#include "../lib/strings.h"
|
||||
#include "../lib/gui.h"
|
||||
#include "../lib/obj/box_lib.h"
|
||||
|
||||
#ifdef LANG_RUS
|
||||
#define WINDOW_TITLE "Словарик 2.4"
|
||||
#define DICTIONARY_LOADED "Словарь загружен"
|
||||
#define WORD_NOT_FOUND "Слово не найдено в словаре"
|
||||
#define ERROR "Ошибка #%d"
|
||||
#else
|
||||
#define WINDOW_TITLE "Dictionary v2.4"
|
||||
#define DICTIONARY_LOADED "Dictionary loaded"
|
||||
#define WORD_NOT_FOUND "Word isn't found in the dictionary"
|
||||
#define ERROR "Error #%d"
|
||||
#endif
|
||||
|
||||
#define TEXT_ENG_RUS "ENG\26RUS"
|
||||
#define TEXT_RUS_ENG "RUS\26ENG"
|
||||
#define TEXT_RU2EN "ENG RUS"
|
||||
#define TEXT_EN2RU "RUS ENG"
|
||||
|
||||
unsigned char speaker[23*40*3]= FROM "speaker.raw";
|
||||
|
||||
proc_info Form;
|
||||
char search_word[256], translate_result[4096];
|
||||
#define TOPH 45
|
||||
#define PRONOUNCED_FILE "/tmp0/1/pronounced.txt"
|
||||
#define SPEECH_PATH "/kolibrios/speech/speech"
|
||||
dword speaker_id;
|
||||
|
||||
unsigned char eng_rus[] = FROM "eng_rus.dict""\0";
|
||||
unsigned char rus_eng[] = FROM "rus_eng.dict""\0";
|
||||
dword io_buffer_data;
|
||||
|
||||
#define ENG_RUS 0
|
||||
#define RUS_ENG 1
|
||||
int active_dict=2;
|
||||
|
||||
#define BTN_CHANGE_LANGUAGE 10
|
||||
#define BTN_SPEAKER 11
|
||||
|
||||
char edit_text[256];
|
||||
edit_box edit1 = {0,13,13,0xffffff,0x94AECE,0xffffff,0xffffff,
|
||||
0x10000000,248,#edit_text,0,ed_focus+ed_always_focus};
|
||||
|
||||
void main()
|
||||
{
|
||||
int btnid;
|
||||
load_dll(boxlib, #box_lib_init,0);
|
||||
OpenDictionary(ENG_RUS);
|
||||
if (param) {
|
||||
strcpy(#edit_text, #param);
|
||||
edit_box_set_text stdcall (#edit1, #param);
|
||||
Translate();
|
||||
}
|
||||
@SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER);
|
||||
loop() switch(@WaitEvent())
|
||||
{
|
||||
case evMouse:
|
||||
edit_box_mouse stdcall (#edit1);
|
||||
break;
|
||||
|
||||
case evButton:
|
||||
btnid = @GetButtonID();
|
||||
if (btnid==01) ExitProcess();
|
||||
if (btnid==BTN_CHANGE_LANGUAGE) {
|
||||
if (active_dict == ENG_RUS) {
|
||||
OpenDictionary(RUS_ENG);
|
||||
} else {
|
||||
OpenDictionary(ENG_RUS);
|
||||
}
|
||||
DrawLangButtons();
|
||||
}
|
||||
if (btnid==BTN_SPEAKER) {
|
||||
if (GetProcessSlot(speaker_id)!=0) {
|
||||
KillProcess(speaker_id);
|
||||
pause(50);
|
||||
} else {
|
||||
if (CreateFile(strlen(#translate_result)+1, #translate_result, PRONOUNCED_FILE)!=0) break;
|
||||
pause(50);
|
||||
speaker_id = RunProgram(SPEECH_PATH, PRONOUNCED_FILE);
|
||||
}
|
||||
SpeakerDraw();
|
||||
}
|
||||
break;
|
||||
|
||||
case evKey:
|
||||
@GetKey();
|
||||
edit_box_key stdcall(#edit1);
|
||||
Translate();
|
||||
break;
|
||||
|
||||
case evReDraw:
|
||||
sc.get();
|
||||
DefineAndDrawWindow(215,120,500,350,0x73,sc.work,WINDOW_TITLE,0);
|
||||
GetProcessInfo(#Form, SelfInfo);
|
||||
if (Form.status_window&ROLLED_UP) break;
|
||||
if (Form.height<140) { MoveSize(OLD,OLD,OLD,140); break; }
|
||||
if (Form.width<400) { MoveSize(OLD,OLD,400,OLD); break; }
|
||||
DrawBar(0, 0, Form.cwidth, TOPH, sc.work); //top bg
|
||||
DrawBar(0, TOPH, Form.cwidth, 1, sc.line);
|
||||
edit1.width = Form.cwidth-edit1.left-edit1.left - 116;
|
||||
edit_box_draw stdcall(#edit1);
|
||||
DrawWideRectangle(edit1.left-2, edit1.top-2, edit1.width+3, 25, 2, 0xffffff);
|
||||
DrawRectangle(edit1.left-3, edit1.top-3, edit1.width+4, 26, sc.line);
|
||||
DrawTranslation();
|
||||
DrawLangButtons();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawLangButtons()
|
||||
{
|
||||
dword direction;
|
||||
int y = edit1.top+3;
|
||||
DrawBar(Form.cwidth-111, y, 100, 25, sc.work);
|
||||
DefineButton(Form.cwidth-79, y-4, 20, 20, BTN_CHANGE_LANGUAGE, sc.button);
|
||||
WriteText(Form.cwidth-73, y-1, 10000001b, sc.button_text, "\26");
|
||||
if (active_dict == ENG_RUS) {
|
||||
direction = TEXT_RU2EN;
|
||||
} else {
|
||||
direction = TEXT_EN2RU;
|
||||
}
|
||||
WriteText(Form.cwidth-111, y, 0x90, sc.work_text, direction);
|
||||
}
|
||||
|
||||
void Translate()
|
||||
{
|
||||
dword tr_start, tr_end;
|
||||
|
||||
sprintf(#search_word, "\10%s\13", #edit_text);
|
||||
strupr(#search_word);
|
||||
|
||||
if (!edit_text) goto _TR_END;
|
||||
|
||||
tr_start = strstr(io_buffer_data, #search_word);
|
||||
if (!tr_start) {
|
||||
strcpy(#translate_result, WORD_NOT_FOUND);
|
||||
} else {
|
||||
tr_start = strchr(tr_start, '"') + 1;
|
||||
tr_end = strchr(tr_start, '"');
|
||||
strlcpy(#translate_result, tr_start, tr_end - tr_start);
|
||||
}
|
||||
_TR_END:
|
||||
strcpy(#search_word, #search_word+1);
|
||||
DrawTranslation();
|
||||
}
|
||||
|
||||
|
||||
void OpenDictionary(dword dict_id)
|
||||
{
|
||||
if (dict_id==active_dict) return;
|
||||
active_dict = dict_id;
|
||||
if (active_dict==ENG_RUS)
|
||||
{
|
||||
io_buffer_data=#eng_rus;
|
||||
strcpy(#search_word, TEXT_ENG_RUS);
|
||||
}
|
||||
if (active_dict==RUS_ENG)
|
||||
{
|
||||
io_buffer_data=#rus_eng;
|
||||
strcpy(#search_word, TEXT_RUS_ENG);
|
||||
}
|
||||
strcpy(#translate_result, DICTIONARY_LOADED);
|
||||
DrawTranslation();
|
||||
}
|
||||
|
||||
|
||||
void DrawTranslation()
|
||||
{
|
||||
int y_pos=TOPH+1;
|
||||
char draw_buf[4096];
|
||||
strlcpy(#draw_buf, #translate_result, sizeof(draw_buf)-1);
|
||||
|
||||
DrawBar(0, y_pos, Form.cwidth, Form.cheight - y_pos, 0xFFFFFF);
|
||||
strttl(#draw_buf);
|
||||
WriteTextB(10+1, y_pos+8, 10000001b, 0x800080, #search_word);
|
||||
|
||||
DrawTextViewArea(10, y_pos+31, Form.cwidth-20, Form.cheight-30,
|
||||
#draw_buf, -1, 0x000000);
|
||||
|
||||
SpeakerDraw();
|
||||
}
|
||||
|
||||
void SpeakerDraw()
|
||||
{
|
||||
dword x = Form.cwidth-38;
|
||||
dword y = Form.cheight-32;
|
||||
if (active_dict == RUS_ENG)
|
||||
{
|
||||
DeleteButton(15);
|
||||
DrawBar(x,y,23,20,0xFFFFFF);
|
||||
} else {
|
||||
DefineHiddenButton(x-5, y-5, 23+10, 20+9, BTN_SPEAKER);
|
||||
if (!GetProcessSlot(speaker_id)) {
|
||||
PutImage(x, y, 23,20, #speaker);
|
||||
} else {
|
||||
PutImage(x, y, 23,20, 23*20*3+#speaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop:
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -1 +0,0 @@
|
||||
■■■щшшЄЄЄ ўўў ЄЄЄ╟─┼╟┼╟··· √√√ЦУХD;A╒╥╘ √∙√╚╟╟╟─╟▀▐▀ щщщmgkC;AC;A┼├─ ъъъ═╩═ыыы ▐█▐╟┼╟╔╟╔√∙√ ╚╞╚SJPE<BE<BE<B┼├┼ р▐▀╚┼╟╠╔╠¤¤¤ ∙ў∙╚╞╚╚┼╟срс ¤¤¤ЭЧЬG?EF>DF>DF>DF>D┼├┼ ЇЇЇ╚┼╟╚┼╟хух ▄▄▄╚┼╟╠╦╠ урс░мн╠╩╩ НИЛH?EH?EH?EH?EH?EH?E╞┼╞ ┘╓┘╚╟╚═╦╦■■■ эээ╚╟╚╚╟╚√√√ЬШЪIAG{ty gafIAGIAGIAGIAGIAGIAG╞─┼ ЁЁЁ╩╟╚╩╟╚ўўў ЇЇЇ╩╟╚╩╟╚єЄєШСХKBHВ{А c\aKBHKBHKBHKBHKBHKBH╚┼╞ ∙∙∙╩╟╚╩╟╚ююю ¤¤¤╩╟╚╩╟╚ьыьСОСLDJЗГЗ _X^LDJLDJLDJLDJLDJLDJ╚┼╞ ╠╩╠╩╟╩цхц ╧╬╧╩╟╩фтфХРУNEKЗБЕ bZ_NEKNEKNEKNEKNEKNEK╚┼╚ ╬╠╠╩╚╩цхц ╤╬╧╩╚╩фффЫЦЪOFLГ|А hafOFLOFLOFLOFLOFLOFL╔┼╚ ∙∙∙╠╚╩╠╚╩ююю ¤¤¤╠╚╩╠╚╩эььеагQHNБ{~ pinQHNQHNQHNQHNQHNQHN╩╞╚ ёёё╠╚╩╠╚╩ўўў їЇЇ╠╚╩╠╚╩єєє∙∙∙хтфёёё ╣╡╖TKQRIORIORIORIORIO╩╞╔ ▄┘█╠╩╠╨═╬ ■ эээ╠╩╠╠╩╠№√№ ╙╨╥d\aSKQSKQSKQSKQ╩╚╔ їЇї═╩╠═╩╠чцч ▀▌▀═╩╠╤╧╧ яэяАy}ULRULRULR╩╚╩ с▀▀═╩╠╤╧╤¤¤¤ ∙∙∙═╦══╩╠фуф ¤¤¤йгжWOUVNT╦╚╦ шцч═╦═ыыы срс═╩═╬╠╬√√√ ╥╬╨ЖАГЁяя √√√╨╠╬═╠═усу ЄЁЁ╧╠═╬══∙∙∙ ■■■шццёЁё ¤¤¤░мо╘╤╙ ўўў ╒╙╒@8>D=Cыъы √√√ЦУХD;A╒╥╘ ■■■ яэяG>DB9?УПТ щщщmgkC;AC;A┼├─ ╕╡╕TLR╜╗╝ ПЙНC;AJBHяэя ╚╞╚RJPD<BD<BD<B┼├┼ ХСХD<BSLQўўў шчшG@ED<BЪХЪ ¤¤¤ЭЧЬG?EF>DF>DF>DF>D┼├┼ ┘╓╫F>DF>Dжве ЙДЙF>DVNT срспмн╠╩╩ НИЛG?EG?EG?EG?EG?EG?E╞┼╞ Аy~G?ESLQ√√√ └╛└G?EG?EєЄєЬЧЩI@F{sx g_dI@FI@FI@FI@FI@FI@F╞─┼ ╠╩╠I@FI@Fурс ▌┌▄I@FI@F╪╓╓ЦСХJBHА{А c\aJBHJBHJBHJBHJBHJBH╞┼╞ ъъъJBHJBH╞┬┼ °°°KCIJBH╝╣╝СМСLCIЗБЕ _W]LCILCILCILCILCILCI╚┼╞ ULRLCIкди `X]LCIвЯбХРУMEKЗБЕ bZ_MEKMEKMEKMEKMEKMEK╚┼╚ VNTMEKкей bZ_MEKгавЫЦЪOFLГ|А hafOFLOFLOFLOFLOFLOFL╔┼╚ ыъыOFLOFL╟┼╞ °°°PGMOFL┐╝╛дагPHNА{~ oinPHNPHNPHNPHNPHNPHN╩╞╚ ╬╠╬PHNPHNфуф ▌▌▌PHNPHN┌╪╪∙∙∙хтфёёё ╣╡╖TKQRIORIORIORIORIO╩╞╔ ЗБЕRIO]U[№√№ ├└┬RIORIOєєє ╙╧╥d[`SJPSJPSJPSJP╩╞╔ ▌█▄SJPSJPмжк ТНРSJPbY_ яэяАy}ULRULRULR╩╚╩ ХПФULRbZ_ЎЎЎ ыъъXOUULRвЭв ¤¤¤йгжWNTVMS╦╚╦ нймZQW╛║╝ ЭЧЪVMS\SYяюя ╨╬╨ДАГЁяя √√√ ёЁё\TZWOUЭЩЬ ╦╔╩YPV]TZыыы №№№нзл═╩╠
|
||||
@@ -1,154 +0,0 @@
|
||||
|
||||
|
||||
:static int __wsprintfproc;
|
||||
:static int cdecl __wsprintf(int buff,mask,...){
|
||||
char buffer[MAX_PATH];
|
||||
char bufnum[32];
|
||||
int bufferlen;
|
||||
int param;
|
||||
int length;
|
||||
int pad;
|
||||
|
||||
struct _wsprintf_mf{
|
||||
int precision;
|
||||
int width;
|
||||
int minus ;
|
||||
int plus ;
|
||||
int diez ;
|
||||
int zero ;
|
||||
byte upcase ;
|
||||
byte _signed;//
|
||||
}mf;
|
||||
|
||||
$push EBX,ESI,EDI;
|
||||
param=#mask[sizeof(mask)];
|
||||
length=0;
|
||||
EDX=mask;
|
||||
EBX=buff;
|
||||
for(;;){
|
||||
mf=0;
|
||||
mf.precision=0x7FFF;
|
||||
REPEATSMALL:
|
||||
if(!DSCHAR[EDX]){
|
||||
AL=0;
|
||||
$call __wsprintfproc;
|
||||
$pop EDI,ESI,EBX;
|
||||
return length;
|
||||
}
|
||||
if(DSCHAR[EDX]!='%'){
|
||||
WRITECHAR: AL=DSCHAR[EDX];$call __wsprintfproc; EDX++;GOTO REPEATSMALL;
|
||||
}
|
||||
|
||||
GETMASK:
|
||||
EDX++;
|
||||
SWITCH(DSCHAR[EDX]){
|
||||
CASE '-': mf.minus++;goto GETMASK;
|
||||
CASE '+': mf.plus ++;goto GETMASK;
|
||||
CASE '#': mf.diez ++;goto GETMASK;
|
||||
CASE '0': mf.zero ++;EDX++;
|
||||
}
|
||||
|
||||
WHILE(DSCHAR[EDX]>='0')&&(DSCHAR[EDX]<='9'){
|
||||
$push EDX;mf.width=mf.width*10+DSCHAR[EDX]-'0';$pop EDX;EDX++;
|
||||
}
|
||||
if(DSCHAR[EDX]=='.'){
|
||||
mf.precision=0;
|
||||
GETPRECISION:
|
||||
EDX++;
|
||||
if(DSCHAR[EDX]>='0')
|
||||
&&(DSCHAR[EDX]<='9'){
|
||||
$push EDX;mf.precision=mf.precision*10+DSCHAR[EDX]-'0';$pop EDX;
|
||||
GOTO GETPRECISION;
|
||||
}
|
||||
}
|
||||
if(DSCHAR[EDX]=='l'){
|
||||
EDX++;
|
||||
}
|
||||
if(DSCHAR[EDX]=='h'){
|
||||
EDX++;
|
||||
}
|
||||
if(DSCHAR[EDX]<'a'){mf.upcase=1;}
|
||||
SWITCH(DSCHAR[EDX]|0x20){
|
||||
CASE 'c': buffer=DSCHAR[param];bufferlen=1;goto FORMAT;
|
||||
CASE 's': if(!DSDWORD[param])DSDWORD[param]="(null)";//??????
|
||||
FOR(bufferlen=0;bufferlen<mf.precision;bufferlen++){
|
||||
AL=DSCHAR[DSDWORD[param]+bufferlen];
|
||||
if(!AL)BREAK;
|
||||
buffer[bufferlen]=AL;
|
||||
}
|
||||
goto FORMAT;
|
||||
}
|
||||
|
||||
//с символьными покончили. теперь числовые
|
||||
if(mf.precision==0x7FFF){mf.precision=mf.width;}
|
||||
if(!mf.precision)mf.precision=1;
|
||||
if(DSCHAR[EDX]|0x20=='x'){
|
||||
$push EDX;
|
||||
EDI=0;//cnt
|
||||
EDX=DSDWORD[param];
|
||||
WHILE(EDX){
|
||||
AL=DL&0xF+0x30;if(AL>'9'){AL+='A'-'9'-1;if(!mf.upcase)AL|=0x20;}
|
||||
bufnum[EDI]=AL;EDI++;EDX>>=4;
|
||||
}
|
||||
$pop EDX;
|
||||
WHILE(EDI<mf.precision){bufnum[EDI]='0';EDI++;}
|
||||
if(mf.diez){bufnum[EDI]=DSCHAR[EDX];EDI++;bufnum[EDI]='0';EDI++;}
|
||||
FOR(bufferlen=0;EDI;bufferlen++){
|
||||
EDI--;buffer[bufferlen]=bufnum[EDI];
|
||||
}
|
||||
goto FORMAT;
|
||||
}
|
||||
switch(DSCHAR[EDX]){
|
||||
CASE 'i':
|
||||
CASE 'd': $push EDX;EDX=DSDWORD[param];
|
||||
if(int EDX<0){-EDX;mf._signed++;}
|
||||
GOTO WRITEINT;
|
||||
CASE 'u': $push EDX;mf.plus=0;EDX=DSDWORD[param];
|
||||
WRITEINT:
|
||||
EDI=0;//cnt
|
||||
WHILE(EDX){
|
||||
EAX=0;EDX><EAX;EAX/=10;EDX><EAX;bufnum[EDI]=AL+'0';EDI++;
|
||||
}
|
||||
WHILE(EDI<mf.precision){bufnum[EDI]='0';EDI++;}
|
||||
if(mf._signed){bufnum[EDI]='-';EDI++;}
|
||||
ELSE
|
||||
if(mf.plus){bufnum[EDI]='+';EDI++;}
|
||||
FOR(bufferlen=0;EDI;bufferlen++){
|
||||
EDI--;buffer[bufferlen]=bufnum[EDI];
|
||||
}
|
||||
$pop EDX;
|
||||
FORMAT:
|
||||
EDX++;
|
||||
param+=sizeof(int);
|
||||
pad=mf.width-bufferlen;if(pad<0)pad=0;
|
||||
if(!mf.minus)$call FRM;
|
||||
FOR(EDI=0;EDI<bufferlen;EDI++){AL=buffer[EDI];$call __wsprintfproc;}
|
||||
if(mf.minus)$call FRM;
|
||||
BREAK;
|
||||
default:
|
||||
goto WRITECHAR;
|
||||
}
|
||||
}//for(;;)
|
||||
FRM: WHILE(pad){AL=' ';$call __wsprintfproc;pad--;}$ret;
|
||||
}
|
||||
|
||||
:int cdecl wsprintf(...)inline{
|
||||
__wsprintfproc=#WSP;
|
||||
goto __wsprintf;
|
||||
WSP: DSCHAR[EBX]=AL;EBX++;$ret;
|
||||
}
|
||||
|
||||
:void FillMemory(int dest,len,byt){
|
||||
EDI = dest;
|
||||
ECX = len;
|
||||
AL = byt;
|
||||
$cld $rep $stosb
|
||||
}
|
||||
|
||||
//#define CopyMemory memmov
|
||||
:void CopyMemory(int dest,src,len){
|
||||
EDI = dest;
|
||||
ESI = src;
|
||||
ECX = len;
|
||||
$cld $rep $movsb
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
if tup.getconfig("NO_CMM") ~= "" then return end
|
||||
if tup.getconfig("LANG") == "ru_RU"
|
||||
then C_LANG = "LANG_RUS"
|
||||
else C_LANG = "LANG_ENG" -- this includes default case without config
|
||||
end
|
||||
tup.rule("diff.c", "c-- /D=$(C_LANG) /OPATH=%o %f" .. tup.getconfig("KPACK_CMD"), "diff.com")
|
||||
@@ -1,5 +0,0 @@
|
||||
@del diff
|
||||
@c-- diff.c
|
||||
@move diff.com diff
|
||||
@del warning.txt
|
||||
@pause
|
||||
@@ -1,208 +0,0 @@
|
||||
//visual text comparer
|
||||
//by den po - jdp@bk.ru
|
||||
|
||||
#define MEMSIZE 1024 * 60
|
||||
#define ENTRY_POINT #main
|
||||
#include "../lib/fs.h"
|
||||
#include "../lib/strings.h"
|
||||
#include "../lib/obj/console.h"
|
||||
|
||||
#define MAX_PATH 260
|
||||
|
||||
#include "32user32.h"
|
||||
#include "objects.h"
|
||||
#include "diff_gui.h"
|
||||
|
||||
#define mincmpstrings 2
|
||||
#define maxcmpstrings 10
|
||||
#define maxcmpoffset 100
|
||||
|
||||
char window_title[] = "Kolibri Diff tool (Visual Text Comparer)";
|
||||
|
||||
char* srcfilename;
|
||||
char* dstfilename;
|
||||
dword srcfile;
|
||||
dword dstfile;
|
||||
dword srcfilesize;
|
||||
dword dstfilesize;
|
||||
TCollection srcfilelines; //file lines
|
||||
TCollection dstfilelines;
|
||||
TCollection srcfilenums; //lines numbers
|
||||
TCollection dstfilenums;
|
||||
|
||||
struct TSimpleCollection:TSortedCollection
|
||||
{
|
||||