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