Subversion Repositories Kolibri OS

Rev

Rev 1411 | 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>	,\
2135 leency 367
    <"/sys/ICON",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
; КОНЕЦ ПРОГРАММЫ