Rev 2135 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
31 | halyavin | 1 | ; |
2 | ; DESKTOP CONTEXT MENU |
||
3 | ; written by Ivan Poddubny |
||
4 | ; |
||
5 | ; Автор - Иван Поддубный |
||
6 | ; e-mail: ivan-yar@bk.ru |
||
7 | ; |
||
8 | ; Compile with flat assembler |
||
9 | ; |
||
2510 | mario79 | 10 | ;------------------------------------------------------------------------------ |
11 | ; version: 1.1 |
||
12 | ; last update: 27/03/2012 |
||
13 | ; changed by: Marat Zakiyanov aka Mario79, aka Mario |
||
14 | ; changes: The program uses only 3404 bytes memory is now. |
||
15 | ; Optimisations and code refactoring. |
||
16 | ;------------------------------------------------------------------------------ |
||
31 | halyavin | 17 | include 'lang.inc' |
485 | heavyiron | 18 | include '..\..\..\macros.inc' |
2510 | mario79 | 19 | ;------------------------------------------------------------------------------ |
20 | use32 |
||
21 | org 0x0 |
||
22 | db 'MENUET01' ; 8 byte id |
||
23 | dd 0x01 ; header version |
||
24 | dd START ; start of code |
||
25 | dd IM_END ; size of image |
||
26 | dd I_END ; memory for app |
||
27 | dd stack_area ; esp |
||
28 | dd 0 ; boot parameters |
||
29 | dd 0 ; path |
||
30 | ;------------------------------------------------------------------------------ |
||
31 | START: |
||
32 | ; получить системные цвета |
||
33 | mcall 48,3,sc,sizeof.system_colors |
||
34 | ; установим маску событий - нас интересует только мышь |
||
35 | mcall 40,100000b |
||
36 | ;------------------------------------------------------------------------------ |
||
37 | align 4 |
||
604 | Rus | 38 | still: ; главный цикл основного процесса |
2510 | mario79 | 39 | mcall 10 ; ждём события |
31 | halyavin | 40 | |
2510 | mario79 | 41 | mcall 37,2 ; какие нажаты кпопки? |
42 | cmp eax,ebx ; если не правая, возврат |
||
43 | jne still |
||
44 | ;-------------------------------------- |
||
45 | ; это для отладки - если мышь в точке (0;0), закроемся |
||
46 | ; xor ebx,ebx |
||
47 | ; mcall 37 |
||
48 | ; test eax,eax ; курсор в точке (0;0), т.е. eax = 0 |
||
49 | ; je exit |
||
50 | ;-------------------------------------- |
||
51 | ; получим число процессов в системе |
||
52 | xor ecx,ecx |
||
53 | mcall 9,procinfo |
||
31 | halyavin | 54 | |
2510 | mario79 | 55 | inc eax ; теперь в eax содержится число процессов + 1 |
56 | mov [processes],eax |
||
57 | mov ecx,1 |
||
58 | ;-------------------------------------- |
||
59 | align 4 |
||
60 | new_process: |
||
61 | pushad |
||
62 | ; получим информацию о процессе; номер - в ecx |
||
63 | mcall 9,procinfo |
||
64 | ; координаты курсора |
||
65 | xor ebx,ebx |
||
66 | mcall 37 |
||
31 | halyavin | 67 | |
2510 | mario79 | 68 | mov ebx,eax ; eax = cursor_x |
69 | shr eax,16 ; ebx = cursor_y |
||
70 | and ebx,0xffff |
||
71 | mov [curx1],eax ; curx1 = cursor_x |
||
72 | mov [cury1],ebx ; cury1 = cursor_y |
||
154 | diamond | 73 | ; \begin{diamond}[18.09.2006] |
74 | ; ignore minimized windows |
||
604 | Rus | 75 | test [procinfo.wnd_state], 2 |
76 | jnz ne_goden |
||
154 | diamond | 77 | ; \end{diamond}[18.09.2006] |
2510 | mario79 | 78 | mov eax,[procinfo.box.left] ; eax = wnd_x_start |
79 | mov ebx,[procinfo.box.top] ; ebx = wnd_y_start |
||
31 | halyavin | 80 | |
2510 | mario79 | 81 | mov ecx,[procinfo.box.width] |
82 | add ecx,eax ; ecx = wnd_x_end |
||
83 | mov edx,[procinfo.box.height] |
||
84 | add edx,ebx ; ecx = wnd_y_end |
||
31 | halyavin | 85 | |
2510 | mario79 | 86 | cmp eax,[curx1] ; wnd_x_start > cursor_x => курсор левее окна |
87 | jg ne_goden |
||
31 | halyavin | 88 | |
2510 | mario79 | 89 | cmp ecx,[curx1] ; wnd_x_end < cursor_x => курсор правее окна |
90 | jl ne_goden |
||
91 | |||
92 | cmp ebx,[cury1] ; wnd_y_start > cursor_y => курсор выше окна |
||
93 | jg ne_goden |
||
94 | |||
95 | cmp edx,[cury1] ; wnd_y_end < cursor_y => курсор ниже окна |
||
96 | jl ne_goden |
||
97 | ;-------------------------------------- |
||
98 | align 4 |
||
604 | Rus | 99 | goden: ; клик был внутри какого-то окна, поэтому ничего не делаем |
2510 | mario79 | 100 | popad |
101 | jmp still |
||
102 | ;-------------------------------------- |
||
103 | align 4 |
||
604 | Rus | 104 | ne_goden: ; клик был снаружи рассматриваемого окна, поэтому |
2510 | mario79 | 105 | popad |
106 | inc ecx |
||
107 | cmp ecx,[processes] |
||
108 | jl new_process ; либо сморим следующее окно, либо запускаем меню |
||
109 | ;-------------------------------------- |
||
110 | align 4 |
||
604 | Rus | 111 | @@: ; подождём, пока пользователь не отпустил правую кнопку мыши |
2510 | mario79 | 112 | mcall 37,2 ; нажаты ли кнопки мыши? |
113 | test eax,ebx ; если отпустил, (eax != 2) |
||
114 | jz @f ; идём в начало главного цикла |
||
31 | halyavin | 115 | |
2510 | mario79 | 116 | mcall 68,1 ; иначе переключимся на следующий поток системы и когда |
117 | jmp @b ; выполнение вернется этому потоку, проверим мышь опять |
||
118 | ;-------------------------------------- |
||
119 | align 4 |
||
31 | halyavin | 120 | @@: |
2510 | mario79 | 121 | ; если уже было открыто меню, нужно подождать, пока оно закроется: |
122 | cmp [menu_opened],0 |
||
123 | je @f |
||
31 | halyavin | 124 | |
2510 | mario79 | 125 | mcall 68,1 ; переключимся на следующий поток системы |
126 | ; более эффективный способ задержки чем mcall 5 |
||
127 | jmp @b |
||
128 | ;-------------------------------------- |
||
129 | align 4 |
||
31 | halyavin | 130 | @@: |
2510 | mario79 | 131 | ; а теперь можно смело запускать процесс (поток) меню |
132 | mcall 51,1,start_wnd,stack_wnd |
||
133 | jmp still |
||
134 | ;------------------------------------------------------------------------------ |
||
135 | align 4 |
||
604 | Rus | 136 | exit_menu: ; если выходим из меню, надо записать в [menu_opened] 0 |
2510 | mario79 | 137 | mov [menu_opened],0 |
138 | ;-------------------------------------- |
||
139 | align 4 |
||
604 | Rus | 140 | exit: ; сюда мы идём, когда выходим из основного процесса |
2510 | mario79 | 141 | or eax,-1 ; eax = -1 |
142 | mcall |
||
143 | ;------------------------------------------------------------------------------ |
||
31 | halyavin | 144 | ; здесь стартует процесс меню |
2510 | mario79 | 145 | ;------------------------------------------------------------------------------ |
146 | align 4 |
||
31 | halyavin | 147 | start_wnd: |
2510 | mario79 | 148 | mov [menu_opened],1 |
149 | ; установим маску желаемых событий: меню + кнопки + перерисовка |
||
150 | mcall 40,100101b |
||
151 | ;------------------------------------------------------------------------------ |
||
152 | align 4 |
||
142 | diamond | 153 | red: |
2510 | mario79 | 154 | call draw_window |
155 | ;------------------------------------------------------------------------------ |
||
156 | align 4 |
||
604 | Rus | 157 | still2: ; главный цикл процесса меню |
2510 | mario79 | 158 | mcall 10 ; ждём события |
31 | halyavin | 159 | |
2510 | mario79 | 160 | cmp eax,1 ; перерисовка? |
161 | je red |
||
162 | |||
163 | cmp eax,3 ; кнопка? |
||
164 | je button |
||
165 | |||
166 | cmp eax,6 ; мышь? |
||
167 | je mouse |
||
31 | halyavin | 168 | |
2510 | mario79 | 169 | jmp still2 ; вернёмся в начало главного цикла |
170 | ;------------------------------------------------------------------------------ |
||
171 | align 4 |
||
31 | halyavin | 172 | ; ОБРАБОТЧИК МЫШИ |
604 | Rus | 173 | mouse: ; когда пользователь нажмёт кнопку мыши, закроемся |
2510 | mario79 | 174 | mcall 37,2 ; какие кнопки нажаты? |
175 | test eax,eax ; никакие? - тогда прекрасно! вернёмся в главный цикл |
||
176 | jz still2 |
||
31 | halyavin | 177 | |
2510 | mario79 | 178 | mcall 37,0 |
179 | |||
1411 | mikedld | 180 | mov esi, eax |
181 | shr esi, 16 |
||
182 | movzx edi, ax |
||
2510 | mario79 | 183 | mcall 9, procinfo, -1 |
184 | |||
185 | mov eax, [procinfo.box.left] |
||
1411 | mikedld | 186 | cmp esi, eax |
187 | jl exit_menu |
||
2510 | mario79 | 188 | |
189 | add eax, [procinfo.box.width] |
||
1411 | mikedld | 190 | cmp esi, eax |
191 | jge exit_menu |
||
2510 | mario79 | 192 | |
193 | mov eax, [procinfo.box.top] |
||
1411 | mikedld | 194 | cmp edi, eax |
195 | jl exit_menu |
||
2510 | mario79 | 196 | |
197 | add eax, [procinfo.box.height] |
||
1411 | mikedld | 198 | cmp edi, eax |
199 | jge exit_menu |
||
31 | halyavin | 200 | |
1411 | mikedld | 201 | jmp still2 |
2510 | mario79 | 202 | ;------------------------------------------------------------------------------ |
203 | align 4 |
||
31 | halyavin | 204 | ; НАЖАТА КНОПКА |
205 | button: |
||
2510 | mario79 | 206 | mcall 17 ; получить идентификатор нажатой кнопки |
31 | halyavin | 207 | |
2510 | mario79 | 208 | sub ah,10 ; сравниваем с 10 |
209 | jl nofuncbtns ; если меньше - закрываем меню |
||
31 | halyavin | 210 | |
2510 | mario79 | 211 | movzx ebx,ah ; получили номер программы в списке в ebx |
212 | mov esi,[startapps + ebx*4] |
||
213 | mov edi,start_info.path |
||
214 | cld |
||
215 | ;-------------------------------------- |
||
216 | align 4 |
||
217 | @@: |
||
218 | lodsb |
||
219 | stosb |
||
220 | test al,al |
||
221 | jnz @b |
||
222 | mcall 70, start_info |
||
31 | halyavin | 223 | |
2510 | mario79 | 224 | ; mov eax,5 ; подождём, пока программа запуститься |
225 | ; mov ebx,1 ; а то её окно не будет отрисовано (баг в ядре???) |
||
226 | ; mcall ; раскомментируйте эти строки, если у вас проблемы |
||
604 | Rus | 227 | ; с отрисовкой |
2510 | mario79 | 228 | ;-------------------------------------- |
229 | align 4 |
||
604 | Rus | 230 | nofuncbtns: ; закрываем меню |
2510 | mario79 | 231 | jmp exit_menu |
232 | ;------------------------------------------------------------------------------ |
||
604 | Rus | 233 | _BTNS_ = 6 ; количество кнопок ("пунктов меню") |
31 | halyavin | 234 | |
235 | if lang eq ru |
||
604 | Rus | 236 | font = 0x00000000 |
237 | string_length = 20 ; длина строки |
||
238 | wnd_x_size = 133 ; ширина окна |
||
239 | title_pos = 36 shl 16 + 7 |
||
31 | halyavin | 240 | else |
604 | Rus | 241 | font = 0x10000000 |
242 | string_length = 12 ; длина строки |
||
243 | wnd_x_size = 105 ; ширина окна |
||
244 | title_pos = 23 shl 16 + 7 |
||
31 | halyavin | 245 | end if |
2510 | mario79 | 246 | ;------------------------------------------------------------------------------ |
31 | halyavin | 247 | ;******************************* |
248 | ;******** РИСУЕМ ОКНО ******** |
||
249 | ;******************************* |
||
250 | draw_window: |
||
2510 | mario79 | 251 | mcall 12,1 ; начинаем "рисовать" |
31 | halyavin | 252 | |
2510 | mario79 | 253 | mov eax,[curx1] ; текущие координаты курсора |
254 | mov [curx],eax ; запишем в координаты окна |
||
255 | mov eax,[cury1] |
||
256 | mov [cury],eax |
||
31 | halyavin | 257 | ; теперь будем считать координаты окна, чтобы оно за край экрана не вылезло |
2510 | mario79 | 258 | mcall 14 ; получим размер экрана |
31 | halyavin | 259 | |
2510 | mario79 | 260 | mov ebx,eax |
261 | shr eax,16 ; в eax - x_screen |
||
262 | and ebx,0xffff ; в ebx - y_screen |
||
263 | add eax,-wnd_x_size ; eax = [x_screen - ширина окна] |
||
264 | add ebx,-_BTNS_*15-21 ; ebx = [y_screen - высота окна] |
||
31 | halyavin | 265 | |
2510 | mario79 | 266 | cmp eax,[curx] |
267 | jg .okx ; если окно слишком близко к правому краю, |
||
268 | add [curx],-wnd_x_size ; сдвинем его влево на 100 |
||
269 | ;-------------------------------------- |
||
270 | align 4 |
||
271 | .okx: |
||
272 | cmp ebx, [cury] |
||
273 | jg .oky ; по вертикали точно также |
||
274 | add [cury], -_BTNS_*15-21 |
||
275 | ;-------------------------------------- |
||
276 | align 4 |
||
277 | .oky: |
||
278 | xor eax, eax ; функция 0 - создать окно |
||
279 | mov ebx, [curx] ; ebx = [координата по x] shl 16 + [ширина] |
||
280 | shl ebx, 16 |
||
281 | add ebx, wnd_x_size |
||
282 | mov ecx, [cury] ; ecx = [координата по y] shl 16 + [высота] |
||
283 | shl ecx, 16 |
||
284 | add ecx, _BTNS_*15+21 |
||
285 | mov edx, [sc.work] ; цвет рабочей области |
||
286 | mov esi, [sc.grab] ; цвет заголовка |
||
287 | or esi, 0x81000000 |
||
288 | mov edi, [sc.frame] ; цвет рамки |
||
289 | mcall |
||
31 | halyavin | 290 | |
2510 | mario79 | 291 | mov eax, 4 ; заголовок |
292 | mov ebx, title_pos ; [x] shl 16 + [y] |
||
293 | mov ecx, [sc.grab_text]; шрифт и цвет (серый) |
||
294 | or ecx, 0x10000000 |
||
31 | halyavin | 295 | |
2510 | mario79 | 296 | push ecx |
297 | push ecx |
||
298 | xor edx,edx |
||
299 | ;-------------------------------------- |
||
300 | align 4 |
||
142 | diamond | 301 | .dec_color: |
2510 | mario79 | 302 | sub byte [esp+edx], 0x33 |
303 | jae @f |
||
304 | mov byte [esp+edx], 0 |
||
305 | ;-------------------------------------- |
||
306 | align 4 |
||
142 | diamond | 307 | @@: |
2510 | mario79 | 308 | inc edx |
309 | jnp .dec_color |
||
310 | pop ecx |
||
311 | mov edx, title ; адрес заголовка |
||
312 | mov esi, title.size ; длина заголовка ("M E N U") |
||
313 | mcall |
||
314 | pop ecx |
||
315 | add ebx, 1 shl 16 ; сдвинем вправо на 1 |
||
316 | mcall |
||
31 | halyavin | 317 | |
2510 | mario79 | 318 | mov ebx, 1*65536+wnd_x_size-2 ; начинаем делать кнопки |
319 | mov ecx, 20*65536+15 |
||
320 | mov edx, 10 or 0x40000000 ; бит 30 установлен => кнопка не рисуется |
||
31 | halyavin | 321 | |
2510 | mario79 | 322 | mov edi,_BTNS_ ; количество кнопок (счётчик) |
323 | ;-------------------------------------- |
||
324 | align 4 |
||
325 | newbtn: ; начало цикла |
||
326 | mcall 8 ; создаём кнопку |
||
31 | halyavin | 327 | |
604 | Rus | 328 | ; пишем текст на кнопке |
2510 | mario79 | 329 | pushad ; спасаем регистры |
330 | shr ecx, 16 |
||
331 | and ebx, 0xffff0000 |
||
332 | add ebx, ecx ; ebx = [x] shl 16 + [y]; |
||
333 | add ebx, 10*65536+4 ; ebx += смещение относительно края кнопки; |
||
334 | mov ecx, [sc.work_text] ; шрифт и цвет |
||
335 | or ecx, font |
||
336 | add edx, -10 ; edx = номер кнопки; |
||
337 | imul edx, string_length ; edx *= длина строки; |
||
338 | add edx, text ; edx += text; теперь в edx адрес строки |
||
339 | mov esi, string_length ; в esi - длина строки |
||
340 | mcall 4 |
||
341 | popad |
||
31 | halyavin | 342 | |
2510 | mario79 | 343 | inc edx ; номер кнопки++; |
344 | add ecx,15*65536 ; увеличим смещение по y |
||
345 | dec edi ; уменьшим счётчик |
||
346 | jnz newbtn ; если не ноль, повторим всё ещё раз |
||
31 | halyavin | 347 | |
2510 | mario79 | 348 | mcall 12,2 ; закончили "рисовать" |
349 | ret ; возврат |
||
350 | ;------------------------------------------------------------------------------ |
||
351 | align 4 |
||
31 | halyavin | 352 | ; ДАННЫЕ ПРОГРАММЫ |
353 | |||
354 | macro strtbl name, [string] |
||
355 | { |
||
356 | common |
||
357 | label name dword |
||
358 | forward |
||
359 | local str |
||
360 | dd str |
||
361 | forward |
||
362 | str db string |
||
363 | } |
||
364 | |||
604 | Rus | 365 | strtbl startapps ,\ |
366 | <"/sys/PIC4",0> ,\ |
||
367 | <"/sys/DESKTOP",0> ,\ |
||
2135 | leency | 368 | <"/sys/ICON",0>,\ |
604 | Rus | 369 | <"/sys/SETUP",0> ,\ |
529 | spraid | 370 | <"/sys/VRR",0> ,\ |
371 | <"/sys/CPU",0> |
||
318 | heavyiron | 372 | |
485 | heavyiron | 373 | sz title, "KolibriOS" |
31 | halyavin | 374 | |
375 | lsz text,\ |
||
376 | en, 'Background ',\ |
||
318 | heavyiron | 377 | en, 'Desktop ',\ |
31 | halyavin | 378 | en, 'Icon manager',\ |
318 | heavyiron | 379 | en, 'Device setup',\ |
31 | halyavin | 380 | en, 'VRR ',\ |
318 | heavyiron | 381 | en, 'Processes ',\ |
31 | halyavin | 382 | \ |
383 | ru, 'Генератор обоев ',\ |
||
318 | heavyiron | 384 | ru, 'Настройка окон ',\ |
31 | halyavin | 385 | ru, 'Управление иконками ',\ |
318 | heavyiron | 386 | ru, 'Настройка устройств ',\ |
387 | ru, 'Настройка монитора ',\ |
||
388 | ru, 'Процессы ' |
||
2510 | mario79 | 389 | ;------------------------------------------------------------------------------ |
390 | align 4 |
||
142 | diamond | 391 | start_info: |
2510 | mario79 | 392 | .mode dd 7 |
393 | dd 0 |
||
394 | .params dd 0 |
||
395 | dd 0 |
||
396 | dd 0 |
||
397 | db 0 |
||
398 | dd start_info.path |
||
399 | ;------------------------------------------------------------------------------ |
||
400 | IM_END: |
||
401 | align 4 |
||
31 | halyavin | 402 | ; НЕИНИЦИАЛИЗИРОВАННЫЕ ДАННЫЕ |
2510 | mario79 | 403 | processes dd ? ; количество процессов в системе |
404 | curx1 dd ? ; координаты курсора |
||
405 | cury1 dd ? |
||
406 | curx dd ? ; координаты окна меню |
||
407 | cury dd ? |
||
31 | halyavin | 408 | |
2510 | mario79 | 409 | menu_opened db ? ; открыто меню или нет? (1-да, 0-нет) |
410 | ;------------------------------------------------------------------------------ |
||
142 | diamond | 411 | align 4 |
2510 | mario79 | 412 | start_info.path rb 256 |
413 | ;------------------------------------------------------------------------------ |
||
414 | align 4 |
||
415 | sc system_colors ; системные цвета |
||
416 | ;------------------------------------------------------------------------------ |
||
417 | align 4 |
||
418 | procinfo process_information ; информация о процессе |
||
419 | ;------------------------------------------------------------------------------ |
||
420 | align 4 |
||
421 | rb 512 ; стэк для окна меню - хватит и 1 Кб |
||
422 | stack_wnd: |
||
423 | ;------------------------------------------------------------------------------ |
||
424 | align 4 |
||
425 | rb 512 |
||
426 | stack_area: |
||
427 | ;------------------------------------------------------------------------------ |
||
428 | I_END: |
||
429 | ;------------------------------------------------------------------------------ |
||
1411 | mikedld | 430 | ; КОНЕЦ ПРОГРАММЫ |
2510 | mario79 | 431 | ;------------------------------------------------------------------------------"/sys/CPU",0>"/sys/VRR",0>"/sys/SETUP",0>"/sys/ICON",0>"/sys/DESKTOP",0>"/sys/PIC4",0>>> |