Subversion Repositories Kolibri OS

Rev

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