/programs/cmm/lib/gui.h |
---|
227,6 → 227,14 |
DrawPopupShadow(x,y,w,h-1,skinned); |
} |
:void Draw3DPopup(dword x,y,w,h) |
{ |
DrawRectangle3D(x,y,w,h, system.color.work_dark, system.color.work_graph); |
DrawBar(x+1,y+1,w-1,1,system.color.work_light); |
DrawBar(x+1,y+2,1,h-2,system.color.work_light); |
DrawPopupShadow(x,y,w,h-1,0); |
} |
:void DrawPopupShadow(dword x,y,w,h,skinned) |
{ |
PutShadow(w+x+1,y,1,h+2,skinned,2); |
291,6 → 299,16 |
PutPixel(x+w+1, y+h, dark); |
} |
:bool is_the_skin_dark() |
{ |
dword bg_col = system.color.work; |
if (GrayScaleImage(#bg_col,1,1)<65) { |
return true; |
} else { |
return false; |
} |
} |
//this function increase falue and return it |
//useful for list of controls which goes one after one |
:struct incn |
/programs/cmm/lib/io.h |
---|
216,6 → 216,28 |
return NULL; |
} |
:void get_path_name(dword BUF,PATH) |
{ |
dword beg = PATH; |
dword pos = PATH; |
dword sav = PATH; |
dword i; |
while(DSBYTE[pos]) |
{ |
if(DSBYTE[pos]=='/')sav = pos; |
pos++; |
} |
i = sav-beg; |
while(i) |
{ |
DSBYTE[BUF] = DSBYTE[beg]; |
beg++; |
BUF++; |
i--; |
} |
DSBYTE[BUF] = 0; |
} |
:struct __PATH |
{ |
dword file(...); |
225,14 → 247,18 |
:char __PATH_NEW[4096]; |
:dword __PATH::path(dword PATH) |
{ |
char self_dir[4096]; |
dword pos; |
if(!PATH) return self.dir; |
get_path_name(#self_dir,I_Path); |
if(!PATH) return #self_dir; |
pos = PATH; |
if(DSBYTE[pos]=='/') || (!strncmp(PATH,"./",2)) |
{ |
return PATH; |
} |
strcpy(#__PATH_NEW, self.dir); |
strcpy(#__PATH_NEW, #self_dir); |
chrcat(#__PATH_NEW, '/'); |
strcpy(#__PATH_NEW, PATH); |
return #__PATH_NEW; |
/programs/cmm/lib/ipc.h |
---|
0,0 → 1,91 |
#ifndef INCLUDE_IPC_H |
#define INCLUDE_IPC_H |
/* |
====================================================================== |
=========== Функция 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC применяется для посылок сообщений от одного процесса/потока |
другому. При этом следует предварительно договориться о том, как |
интерпретировать конкретное сообщение. |
-------- Подфункция 1 - установить область для получения IPC --------- |
Вызывается процессом-приёмником. |
Параметры: |
* eax = 60 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = указатель на буфер |
* edx = размер буфера |
Возвращаемое значение: |
* eax = 0 - всегда успешно |
Формат IPC-буфера: |
* +0: dword: если здесь не 0, то буфер считается заблокированным; |
блокируйте/разблокируйте буфер, когда вы с ним активно работаете |
и вам надо, чтобы извне не изменялись данные буфера |
(не поступали новые сообщения) |
* +4: dword: занято места в буфере (в байтах) |
* +8: первое сообщение |
* +8+n: второе сообщение |
* ... |
Формат сообщения: |
* +0: dword: PID процесса/потока, пославшего сообщение |
* +4: dword: длина сообщения (не считая этот заголовок) |
* +8: n*byte: данные сообщения |
--------------- Подфункция 2 - послать сообщение IPC. ---------------- |
Вызывается процессом-инициатором. |
Параметры: |
* eax = 60 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = PID приёмника |
* edx = указатель на данные сообщения |
* esi = длина сообщения (в байтах) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - приёмник не определил буфер для IPC-сообщений |
(может быть, ещё не успел, а может быть, это не тот поток, |
который нужен) |
* eax = 2 - приёмник заблокировал IPC-буфер; |
попробуйте немного подождать |
* eax = 3 - переполнение IPC-буфера приёмника |
* eax = 4 - процесса/потока с таким PID не существует |
Замечания: |
* Система сразу после записи IPC-сообщения в буфер посылает |
потоку-приёмнику событие с кодом 7 (см. коды событий). |
---------------------- Константы для регистров: ---------------------- |
eax - SF_IPC (60) |
ebx - SSF_SET_AREA (1), SSF_SEND_MESSAGE (2) |
*/ |
inline fastcall void IpcSetArea(ECX, EDX) |
{ |
$eax, 60 |
$ebx, 1 |
// ecx = указатель на буфер |
// edx = размер буфера |
$int 64 |
// eax = 0 - всегда успешно |
} |
inline fastcall int SendIpcMessage(ECX, EDX, ESI) |
{ |
$eax, 60 |
$ebx, 2 |
// ecx = PID приёмника |
// edx = указатель на данные сообщения |
// esi = длина сообщения (в байтах) |
$int 64 |
// eax = 0 - успешно |
// eax = 1 - приёмник не определил буфер для IPC-сообщений |
// (может быть, ещё не успел, а может быть, это |
// не тот поток, который нужен) |
// eax = 2 - приёмник заблокировал IPC-буфер; |
// попробуйте немного подождать |
// eax = 3 - переполнение IPC-буфера приёмника |
// eax = 4 - процесса/потока с таким PID не существует |
} |
#endif |
/programs/cmm/lib/kolibri.h |
---|
661,67 → 661,17 |
DrawBar(x+37,y+10,2,2,color); |
} |
:void __path_name__(dword BUF,PATH) |
{ |
dword beg = PATH; |
dword pos = PATH; |
dword sav = PATH; |
dword i; |
while(DSBYTE[pos]) |
{ |
if(DSBYTE[pos]=='/')sav = pos; |
pos++; |
} |
i = sav-beg; |
while(i) |
{ |
DSBYTE[BUF] = DSBYTE[beg]; |
beg++; |
BUF++; |
i--; |
} |
/*while(DSBYTE[beg]) |
{ |
DSBYTE[BUF1] = DSBYTE[beg]; |
beg++; |
BUF1++; |
}*/ |
//DSBYTE[BUF1] = 0; |
DSBYTE[BUF] = 0; |
} |
char __BUF_DIR__[4096]; |
:struct SELF |
{ |
dword dir; |
dword file; |
dword path; |
} self; |
dword __generator; // random number generator init |
dword __generator; // random number generator - äëÿ ãåíåðàöèè ñëó÷àéíûõ ÷èñåë |
:dword program_path_length; |
//The initialization of the initial data before running |
void ______INIT______() |
{ |
//if (program_path[0]!='/') I_Path++; |
self.dir = #__BUF_DIR__; |
self.file = 0; |
self.path = I_Path; |
__path_name__(#__BUF_DIR__,I_Path); |
skin_height = GetSkinHeight(); |
screen.width = GetScreenWidth()+1; |
screen.height = GetScreenHeight()+1; |
__generator = GetStartTime(); |
mem_init(); |
main(); |
ExitProcess(); |
} |
______STOP______: |
#endif |
732,4 → 682,8 |
#ifndef INCLUDE_DEBUG_H |
#include "../lib/debug.h" |
#endif |
#ifndef INCLUDE_IPC_H |
#include "../lib/ipc.h" |
#endif |
/programs/cmm/lib/mem.h |
---|
98,7 → 98,33 |
} |
} |
inline fastcall dword memopen(ECX, EDX, ESI) |
{ |
$push ebx |
$mov eax, 68 |
$mov ebx, 22 |
// ecx = area name, 31 symbols max |
// edx = area size for SHM_CREATE SHM_OPEN_ALWAYS |
// esi = flags, see the list below: |
#define SHM_OPEN 0x00 |
#define SHM_OPEN_ALWAYS 0x04 |
#define SHM_CREATE 0x08 |
#define SHM_READ 0x00 |
#define SHM_WRITE 0x01 |
$int 0x40 |
$pop ebx |
// eax, edx - please check system documentation |
} |
inline fastcall dword memclose(ECX) |
{ |
$push ebx |
$mov eax, 68 |
$mov ebx, 23 |
$int 0x40 |
$pop ebx |
// eax destroyed |
} |
#define mem_Alloc malloc |
#define mem_ReAlloc realloc |
/programs/cmm/menu/Tupfile.lua |
---|
0,0 → 1,6 |
if tup.getconfig("NO_CMM") ~= "" then return end |
if tup.getconfig("LANG") == "ru" |
then C_LANG = "LANG_RUS" |
else C_LANG = "LANG_ENG" -- this includes default case without config |
end |
tup.rule("menu.c", "c-- /D=AUTOBUILD /D=$(C_LANG) %f" .. tup.getconfig("KPACK_CMD"), "menu.com") |
/programs/cmm/menu/build.bat |
---|
0,0 → 1,5 |
@del menu |
@c-- menu.c |
@rename menu.com menu |
@del warning.txt |
@pause |
/programs/cmm/menu/menu.c |
---|
0,0 → 1,180 |
#define MEMSIZE 4096*40 |
#include "../lib/io.h" |
#include "../lib/gui.h" |
#include "../lib/collection.h" |
#include "../lib/list_box.h" |
#include "../lib/fs.h" |
#define ITEM_H 19 |
llist menu1; |
collection names; |
collection hotkeys; |
dword shared_mem; |
int win_x, win_y; |
int max_name_len; |
int max_hotkey_len; |
int selected = 0; |
dword cur_param = #param; |
int GetNextParam() |
{ |
int result; |
dword next_param = strchr(cur_param, ' '); |
ESBYTE[next_param] = '\0'; |
result = atoi(cur_param); |
cur_param = next_param+1; |
return result; |
} |
void GetWindowPosition() |
{ |
int position; |
shared_mem = GetNextParam(); |
debugval("shared_mem", ESDWORD[shared_mem]); |
win_x = GetNextParam(); |
win_y = GetNextParam(); |
selected = GetNextParam(); |
position = GetNextParam(); |
if (position==2) win_x -= menu1.w; |
if (position==3) { |
win_x -= menu1.w; |
win_y -= menu1.h; |
} |
if (position==4) win_y -= menu1.h; |
} |
void GetMenuItems(dword current_name) |
{ |
dword next_name = strchr(current_name, '\n'); |
dword hotkey = strchr(current_name, '|'); |
ESBYTE[next_name] = '\0'; |
if (hotkey) && (hotkey < next_name) { |
ESBYTE[hotkey] = '\0'; |
} else { |
if (hotkey) && (!next_name) { |
ESBYTE[hotkey] = '\0'; |
} else { |
hotkey = " "; |
} |
} |
hotkeys.add(hotkey+1); |
names.add(current_name); |
if (next_name) GetMenuItems(next_name+2); |
} |
void main() |
{ |
proc_info Form; |
GetMenuItems(strchr(#param, '\n') + 2); |
max_name_len = strlen(names.get(0)) * 6; |
max_hotkey_len = strlen(hotkeys.get(0)) * 6; |
//selected = ESDWORD[shared_mem]; |
menu1.count = names.count; |
menu1.SetFont(6, 9, 0x80); |
menu1.SetSizes(2,2, max_name_len + max_hotkey_len + 23, menu1.count*ITEM_H, ITEM_H); |
menu1.cur_y = -1; |
GetWindowPosition(); |
SetEventMask(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE); |
loop() switch(WaitEvent()) |
{ |
case evMouse: |
GetProcessInfo(#Form, SelfInfo); |
if (!CheckActiveProcess(Form.ID)) exit(); |
mouse.get(); |
if (menu1.ProcessMouse(mouse.x, mouse.y)) draw_list(); |
if (mouse.lkm)&&(mouse.up) click(); |
break; |
case evKey: |
GetKeys(); |
ProcessKeys(); |
break; |
case evReDraw: |
DefineAndDrawWindow(win_x, win_y, menu1.w+4, menu1.h+3, 0x01, 0, 0, 0x01fffFFF); |
system.color.get(); |
Draw3DPopup(0,0,menu1.w+2,menu1.h+2); |
draw_list(); |
} |
} |
void ProcessKeys() |
{ |
switch(key_scancode) |
{ |
case SCAN_CODE_ESC: |
exit(); |
case SCAN_CODE_ENTER: |
click(); |
case SCAN_CODE_DOWN: |
if (!menu1.KeyDown()) menu1.KeyHome(); |
draw_list(); |
break; |
case SCAN_CODE_UP: |
if (!menu1.KeyUp()) menu1.KeyEnd(); |
draw_list(); |
break; |
default: |
if (menu1.ProcessKey(key_scancode)) draw_list(); |
} |
} |
void draw_list() |
{ |
int i, item_y; |
dword active_background_color = MixColors(system.color.work_button, system.color.work,230); |
dword active_top_border_color = MixColors(system.color.work_graph, system.color.work_button,240); |
dword inactive_text_shadow_color = MixColors(system.color.work,0xFFFfff,150); |
dword text_color; |
bool skin_dark = is_the_skin_dark(); |
for (i=0; i<menu1.count; i++;) |
{ |
item_y = i*ITEM_H+menu1.y; |
if (i==menu1.cur_y) { |
text_color = system.color.work_button_text; |
DrawBar(menu1.x, item_y+1, menu1.w, ITEM_H-2, active_background_color); |
DrawBar(menu1.x, item_y, menu1.w, 1, active_top_border_color); |
DrawBar(menu1.x, item_y+ITEM_H-1, menu1.w, 1, system.color.work_light); |
WriteText(13 + max_name_len, item_y + menu1.text_y, 0x80, text_color, hotkeys.get(i)); |
} else { |
text_color = system.color.work_text; |
DrawBar(menu1.x, item_y, menu1.w, ITEM_H, system.color.work); |
if (!skin_dark) WriteText(13+1, item_y + menu1.text_y +1, 0x80, inactive_text_shadow_color, names.get(i)); |
WriteText(13 + max_name_len, item_y + menu1.text_y, 0x80, system.color.work_graph, hotkeys.get(i)); |
} |
WriteText(13, item_y + menu1.text_y, 0x80, text_color, names.get(i)); |
} |
if (selected) WriteText(5, selected*ITEM_H + menu1.y + menu1.text_y, 0x80, 0xEE0000, "\x10"); |
} |
void click() |
{ |
ESDWORD[shared_mem] = menu1.cur_y + 1; |
ExitProcess(); |
} |
void exit() |
{ |
ESDWORD[shared_mem] = 0; |
ExitProcess(); |
} |