Subversion Repositories Kolibri OS

Rev

Rev 2426 | Rev 2508 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 2455 $
9
 
10
WINDOW_MOVE_AND_RESIZE_FLAGS = \
11
  mouse.WINDOW_RESIZE_N_FLAG + \
12
  mouse.WINDOW_RESIZE_W_FLAG + \
13
  mouse.WINDOW_RESIZE_S_FLAG + \
14
  mouse.WINDOW_RESIZE_E_FLAG + \
15
  mouse.WINDOW_MOVE_FLAG
16
 
17
uglobal
18
align 4
19
  event_start   dd ?
20
  event_end     dd ?
21
  event_uid     dd 0
22
endg
23
EV_SPACE   = 512
24
FreeEvents = event_start-EVENT.fd    ; "виртуальный" event, используются только поля:
25
                                     ;  FreeEvents.fd=event_start и FreeEvents.bk=event_end
26
align 4
27
init_events:                                       ;; used from kernel.asm
2384 hidnplayr 28
        stdcall kernel_alloc, EV_SPACE*sizeof.EVENT
2288 clevermous 29
        or      eax, eax
30
        jz      .fail
31
      ; eax - current event, ebx - previos event below
32
        mov     ecx, EV_SPACE        ; current - in allocated space
33
        mov     ebx, FreeEvents      ; previos - начало списка
34
        push    ebx                  ; оно же и конец потом будет
35
  @@:
36
        mov     [ebx+EVENT.fd], eax
37
        mov     [eax+EVENT.bk], ebx
38
        mov     ebx, eax             ; previos <- current
2384 hidnplayr 39
        add     eax, sizeof.EVENT    ; new current
2288 clevermous 40
        loop    @b
41
        pop     eax                  ; вот оно концом и стало
42
        mov     [ebx+EVENT.fd], eax
43
        mov     [eax+EVENT.bk], ebx
44
.fail:
45
        ret
46
 
47
EVENT_WATCHED    equ 0x10000000 ;бит 28
48
EVENT_SIGNALED   equ 0x20000000 ;бит 29
49
MANUAL_RESET     equ 0x40000000 ;бит 30
50
MANUAL_DESTROY   equ 0x80000000 ;бит 31
51
 
52
align 4
53
create_event:                                      ;; EXPORT use
54
;info:
55
;   Переносим EVENT из списка FreeEvents в список ObjList текущего слота
56
;   EVENT.state устанавливаем из ecx, EVENT.code косвенно из esi (если esi<>0)
57
;param:
58
;   esi - event data
59
;   ecx - flags
60
;retval:
61
;   eax - event (=0 => fail)
62
;   edx - uid
63
;scratched: ebx,ecx,esi,edi
64
        mov     ebx, [current_slot]
65
        add     ebx, APP_OBJ_OFFSET
66
        mov     edx, [TASK_BASE]
67
        mov     edx, [edx+TASKDATA.pid]
68
        pushfd
69
        cli
70
 
71
set_event:                                         ;; INTERNAL use !!! don't use for Call
72
;info:
73
;   Берем новый event из FreeEvents, заполняем его поля, как указано в ecx,edx,esi
74
;   и устанавливаем в список, указанный в ebx.
75
;   Возвращаем сам event (в eax), и его uid (в edx)
76
;param:
77
;   ebx - start-chain "virtual" event for entry new event Right of him
78
;   ecx - flags      (copied to EVENT.state)
79
;   edx - pid        (copied to EVENT.pid)
80
;   esi - event data (copied to EVENT.code indirect, =0 => skip)
81
;retval:
82
;   eax - event (=0 => fail)
83
;   edx - uid
84
;scratched: ebx,ecx,esi,edi
85
        mov     eax, FreeEvents
86
        cmp     eax, [eax+EVENT.fd]
87
        jne     @f  ; not empty ???
88
        pushad
89
        call    init_events
90
        popad
91
        jz      RemoveEventTo.break ; POPF+RET
92
  @@:
93
        mov     eax, [eax+EVENT.fd]
94
        mov     [eax+EVENT.magic], 'EVNT'
95
        mov     [eax+EVENT.destroy], destroy_event.internal
96
        mov     [eax+EVENT.state], ecx
97
        mov     [eax+EVENT.pid], edx
98
        inc     [event_uid]
99
        Mov     [eax+EVENT.id],edx,[event_uid]
100
        or      esi, esi
101
        jz      RemoveEventTo
102
        lea     edi, [eax+EVENT.code]
2384 hidnplayr 103
        mov     ecx, (sizeof.EVENT -EVENT.code)/4
2288 clevermous 104
        cld
105
        rep movsd
106
 
107
RemoveEventTo:                                     ;; INTERNAL use !!! don't use for Call
108
;param:
109
;   eax - указатель на event, КОТОРЫЙ вставляем
110
;   ebx - указатель на event, ПОСЛЕ которого вставляем
111
;scratched: ebx,ecx
112
        mov     ecx, eax             ; ecx=eax=Self,      ebx=NewLeft
113
        xchg    ecx, [ebx+EVENT.fd]  ; NewLeft.fd=Self,   ecx=NewRight
114
        cmp     eax, ecx             ; стоп, себе думаю...
115
        je      .break               ; - а не дурак ли я?
116
        mov     [ecx+EVENT.bk], eax  ; NewRight.bk=Self
117
        xchg    ebx, [eax+EVENT.bk]  ; Self.bk=NewLeft,   ebx=OldLeft
118
        xchg    ecx, [eax+EVENT.fd]  ; Self.fd=NewRight,  ecx=OldRight
119
        mov     [ebx+EVENT.fd], ecx  ; OldLeft.fd=OldRight
120
        mov     [ecx+EVENT.bk], ebx  ; OldRight.bk=OldLeft
121
.break:
122
        popfd
123
        ret
124
 
125
align 4
126
NotDummyTest:                                      ;; INTERNAL use (not returned for fail !!!)
127
        pop     edi
128
        call    DummyTest ; not returned for fail !!!
129
        mov     ebx, eax
130
        mov     eax, [ebx+EVENT.pid]
131
        push    edi
132
.small: ; криво как-то...
133
        pop     edi
134
        pushfd
135
        cli
136
        call    pid_to_slot ; saved all registers (eax - retval)
137
        shl     eax, 8
138
        jz      RemoveEventTo.break ; POPF+RET
139
        jmp     edi ; штатный возврат
140
 
141
align 4
142
raise_event:                                       ;; EXPORT use
143
;info:
144
;   Устанавливаем данные EVENT.code
145
;   Если там флаг EVENT_SIGNALED уже активен - больше ничего
146
;   Иначе: этот флаг взводится, за исключением случая наличия флага EVENT_WATCHED в edx
147
;   В этом случае EVENT_SIGNALED взводится лишь при наличие EVENT_WATCHED в самом событии
148
;param:
149
;   eax - event
150
;   ebx - uid (for Dummy testing)
151
;   edx - flags
152
;   esi - event data (=0 => skip)
153
;scratched: ebx,ecx,esi,edi
154
        call    NotDummyTest ; not returned for fail !!!
155
        or      esi, esi
156
        jz      @f
157
        lea     edi, [ebx+EVENT.code]
2384 hidnplayr 158
        mov     ecx, (sizeof.EVENT -EVENT.code)/4
2288 clevermous 159
        cld
160
        rep movsd
161
  @@:
162
        test    byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
163
        jnz     RemoveEventTo.break  ; POPF+RET
164
        bt      edx, 28 ;EVENT_WATCHED
165
        jnc     @f
166
        test    byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24
167
        jz      RemoveEventTo.break  ; POPF+RET
168
  @@:
169
        or      byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
170
        add     eax, SLOT_BASE+APP_EV_OFFSET
171
        xchg    eax, ebx
172
        jmp     RemoveEventTo
173
 
174
align 4
175
clear_event:                                       ;; EXPORT use
176
;info:
177
;
178
;param:
179
;   eax - event
180
;   ebx - uid (for Dummy testing)
181
;scratched: ebx,ecx
182
        call    NotDummyTest ; not returned for fail !!!
183
        add     eax, SLOT_BASE+APP_OBJ_OFFSET
184
        and     byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
185
        xchg    eax, ebx
186
        jmp     RemoveEventTo
187
 
188
align 4
189
send_event:                                        ;; EXPORT use
190
;info:
191
;   Создает новый EVENT (вытаскивает из списка FreeEvents) в списке EventList
192
;   целевого слота (eax=pid), с данными из esi косвенно, и state=EVENT_SIGNALED
193
;param:
194
;   eax - slots pid, to sending new event
195
;   esi - pointer to sending data (in code field of new event)
196
;retval:
197
;   eax - event (=0 => fail)
198
;   edx - uid
199
;warning:
200
;   may be used as CDECL with such prefix...
201
;       mov     esi,[esp+8]
202
;       mov     eax,[esp+4]
203
;   but not as STDCALL :(
204
;scratched: ebx,ecx,esi,edi
205
        mov     edx, eax
206
        call    NotDummyTest.small ; not returned for fail !!!
207
        lea     ebx, [eax+SLOT_BASE+APP_EV_OFFSET]
208
        mov     ecx, EVENT_SIGNALED
209
        jmp     set_event
210
 
211
align 4
212
DummyTest:                                         ;; INTERNAL use (not returned for fail !!!)
213
;param:
214
;   eax - event
215
;   ebx - uid (for Dummy testing)
216
        cmp     [eax+EVENT.magic], 'EVNT'
217
        jne     @f
218
        cmp     [eax+EVENT.id], ebx
219
        je      .ret
220
  @@:
221
        pop     eax
222
        xor     eax, eax
223
.ret:
224
        ret
225
 
226
 
227
align 4
228
Wait_events:
229
        or      ebx, -1; infinite timeout
230
Wait_events_ex:
231
;info:
232
;   Ожидание "абстрактного" события через перевод слота в 5-ю позицию.
233
;   Абстрактность заключена в том, что факт события определяется функцией APPDATA.wait_test,
234
;   которая задается клиентом и может быть фактически любой.
235
;   Это позволяет shed-у надежно определить факт события, и не совершать "холостых" переключений,
236
;   предназначенных для разборок типа "свой/чужой" внутри задачи.
237
;param:
238
;   edx - wait_test, клиентская ф-я тестирования (адрес кода)
239
;   ecx - wait_param, дополнительный параметр, возможно необходимый для [wait_test]
240
;   ebx - wait_timeout
241
;retval:
242
;   eax - результат вызова [wait_test] (=0 => timeout)
243
;scratched: esi
244
        mov     esi, [current_slot]
245
        mov     [esi+APPDATA.wait_param], ecx
246
        pushad
247
        mov     ebx, esi;пока это вопрос, чего куды сувать..........
248
        pushfd  ; это следствие общей концепции: пусть ф-я тестирования имеет
249
        cli     ; право рассчитывать на закрытые прерывания, как при вызове из shed
250
        call    edx
251
        popfd
252
        mov     [esp+28], eax
253
        popad
254
        or      eax, eax
255
        jnz     @f   ;RET
256
        mov     [esi+APPDATA.wait_test], edx
257
        mov     [esi+APPDATA.wait_timeout], ebx
258
        Mov     [esi+APPDATA.wait_begin],eax,[timer_ticks]
259
        mov     eax, [TASK_BASE]
260
        mov     [eax+TASKDATA.state], 5
261
        call    change_task
262
        mov     eax, [esi+APPDATA.wait_param]
263
  @@:
264
        ret
265
 
266
align 4
267
wait_event:                                        ;; EXPORT use
268
;info:
269
;   Ожидание флага EVENT_SIGNALED в совершенно конкретном Event
270
;   (устанавливаемого, надо полагать, через raise_event)
271
;   При активном флаге MANUAL_RESET - больше ничего
272
;   Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются,
273
;   и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота,
274
;   а при не активном - уничтожается штатно (destroy_event.internal)
275
;param:
276
;   eax - event
277
;   ebx - uid (for Dummy testing)
278
;scratched: ecx,edx,esi
279
        call    DummyTest
280
        mov     ecx, eax             ; wait_param
281
        mov     edx, get_event_alone ; wait_test
282
        call    Wait_events          ; timeout ignored
283
        jmp     wait_finish
284
 
285
align 4
286
get_event_ex:                                      ;; f68:14
287
;info:
288
;   Ожидание любого события в очереди EventList текущего слота
289
;   Данные события code - копируются в память приложения (косвенно по edi)
290
;   При активном флаге MANUAL_RESET - больше ничего
291
;   Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются,
292
;   и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота,
293
;   а при не активном - уничтожается штатно (destroy_event.internal)
294
;param:
295
;   edi - адрес в коде приложения для копирования данных из EVENT.code
296
;retval:
297
;   eax - собственно EVENT (будем называть это его хэндлом)
298
;scratched: ebx,ecx,edx,esi,edi
299
        mov     edx, get_event_queue ; wait_test
300
        call    Wait_events          ; timeout ignored
301
        lea     esi, [eax+EVENT.code]
2384 hidnplayr 302
        mov     ecx, (sizeof.EVENT-EVENT.code)/4
2288 clevermous 303
        cld
304
        rep movsd
2384 hidnplayr 305
        mov     byte[edi-(sizeof.EVENT-EVENT.code)+2], cl;clear priority field
2288 clevermous 306
wait_finish:
307
        test    byte[eax+EVENT.state+3], MANUAL_RESET shr 24
308
        jnz     get_event_queue.ret  ; RET
309
        and     byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
310
        test    byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24
311
        jz      destroy_event.internal
312
        mov     ebx, [current_slot]
313
        add     ebx, APP_OBJ_OFFSET
314
        pushfd
315
        cli
316
        jmp     RemoveEventTo
317
 
318
align 4
319
destroy_event:                                     ;; EXPORT use
320
;info:
321
;   Переносим EVENT в список FreeEvents, чистим поля magic,destroy,pid,id
322
;param:
323
;   eax - event
324
;   ebx - uid (for Dummy testing)
325
;retval:
326
;   eax - адрес объекта EVENT (=0 => fail)
327
;scratched: ebx,ecx
328
        call    DummyTest ; not returned for fail !!!
329
.internal:
330
        xor     ecx, ecx  ; clear common header
331
        pushfd
332
        cli
333
        mov     [eax+EVENT.magic], ecx
334
        mov     [eax+EVENT.destroy], ecx
335
        mov     [eax+EVENT.pid], ecx
336
        mov     [eax+EVENT.id], ecx
337
        mov     ebx, FreeEvents
338
        jmp     RemoveEventTo
339
 
340
align 4
341
get_event_queue:
342
;info:
343
;   клиентская ф-я тестирования для get_event_ex
344
;warning:
345
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
346
;  -may be assumed, that interrupt are disabled
347
;  -it is not restriction for scratched registers
348
;param:
349
;   ebx - адрес APPDATA слота тестирования
350
;retval:
351
;   eax - адрес объекта EVENT (=0 => fail)
352
        add     ebx, APP_EV_OFFSET
353
        mov     eax, [ebx+APPOBJ.bk] ; выбираем с конца, по принципу FIFO
354
        cmp     eax, ebx ; empty ???
355
        je      get_event_alone.ret0
356
.ret:
357
        ret
358
 
359
align 4
360
get_event_alone:
361
;info:
362
;   клиентская ф-я тестирования для wait_event
363
;warning:
364
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
365
;  -may be assumed, that interrupt are disabled
366
;  -it is not restriction for scratched registers
367
;param:
368
;   ebx - адрес APPDATA слота тестирования
369
;retval:
370
;   eax - адрес объекта EVENT (=0 => fail)
371
        mov     eax, [ebx+APPDATA.wait_param]
372
        test    byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24
373
        jnz     .ret
374
        or      byte[eax+EVENT.state+3], EVENT_WATCHED shr 24
375
.ret0:
376
        xor     eax, eax; NO event!!!
377
.ret:
378
        ret
379
 
380
align 4
381
sys_sendwindowmsg:                                 ;; f72
382
        dec     ebx
383
        jnz     .ret ;subfunction==1 ?
384
       ;pushfd  ;а нафига?
385
        cli
386
        sub     ecx, 2
387
        je      .sendkey
388
        dec     ecx
389
        jnz     .retf
390
.sendbtn:
391
        cmp     byte[BTN_COUNT], 1
392
        jae     .result ;overflow
393
        inc     byte[BTN_COUNT]
394
        shl     edx, 8
395
        mov     [BTN_BUFF], edx
396
        jmp     .result
397
.sendkey:
398
        movzx   eax, byte[KEY_COUNT]
399
        cmp     al, 120
400
        jae     .result ;overflow
401
        inc     byte[KEY_COUNT]
402
        mov     [KEY_COUNT+1+eax], dl
403
.result:
404
        setae   byte[esp+32] ;считаем, что исходно: dword[esp+32]==72
405
.retf: ;popfd
406
.ret:
407
        ret
408
 
409
align 4
410
sys_getevent:                                      ;; f11
411
        mov     ebx, [current_slot];пока это вопрос, чего куды сувать..........
412
        pushfd  ; это следствие общей концепции: пусть ф-я тестирования имеет
413
        cli     ; право рассчитывать на закрытые прерывания, как при вызове из shed
414
        call    get_event_for_app
415
        popfd
416
        mov     [esp+32], eax
417
        ret
418
 
419
align 4
420
sys_waitforevent:                                  ;; f10
421
        or      ebx, -1; infinite timeout
422
sys_wait_event_timeout:                            ;; f23
423
        mov     edx, get_event_for_app; wait_test
424
        call    Wait_events_ex        ; ebx - timeout
425
        mov     [esp+32], eax
426
        ret
427
 
428
align 4
429
get_event_for_app:                                 ;; used from f10,f11,f23
430
;info:
431
;   клиентская ф-я тестирования для приложений (f10,f23)
432
;warning:
433
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
434
;  -may be assumed, that interrupt are disabled
435
;  -it is not restriction for scratched registers
436
;param:
437
;   ebx - адрес APPDATA слота тестирования
438
;retval:
439
;   eax - номер события (=0 => no events)
440
        movzx   edi, bh               ; bh  is assumed as [CURRENT_TASK]
441
        shl     edi, 5
442
        add     edi, CURRENT_TASK     ; edi is assumed as [TASK_BASE]
443
        mov     ecx, [edi+TASKDATA.event_mask]
2411 Serge 444
        and     ecx, 0x7FFFFFFF
2288 clevermous 445
.loop: ; пока не исчерпаем все биты маски
446
        bsr     eax, ecx       ; находим ненулевой бит маски (31 -> 0)
447
        jz      .no_events     ; исчерпали все биты маски, но ничего не нашли ???
448
        btr     ecx, eax       ; сбрасываем проверяемый бит маски
449
       ; переходим на обработчик этого (eax) бита
450
        cmp     eax, 9
451
        jae     .loop          ; eax=[9..31], ignored
452
        cmp     eax, 3
453
        je      .loop          ; eax=3, ignored
454
        ja      .FlagAutoReset ; eax=[4..8], retvals=eax+1
455
        cmp     eax, 1
456
        jae     .BtKy          ; eax=[1,2],  retvals=eax+1
457
.WndRedraw:                    ; eax=0, retval WndRedraw=1
458
        cmp     [edi-twdw+WDATA.fl_redraw], al;al==0
459
        jne     .result
460
        jmp     .loop
461
  .no_events:
462
        xor     eax, eax
463
        ret
464
 
465
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9
2424 mario79 466
        cmp     eax, 5; Mouse 5+1=6
2426 mario79 467
        jne     .no_mouse_check
2424 mario79 468
        push    eax
2426 mario79 469
        mov     eax, [TASK_BASE]
470
        mov     eax, [eax + TASKDATA.event_mask]
471
        test    eax, 0x80000000 ; bit 31: active/inactive filter f.40
472
        jz      @f
473
        pop     eax
474
        jmp     .no_mouse_check
475
@@:
2288 clevermous 476
; If the window is captured and moved by the user, then no mouse events!!!
2424 mario79 477
        mov     al, [mouse.active_sys_window.action]
478
        and     al, WINDOW_MOVE_AND_RESIZE_FLAGS
479
        test    al, al
480
        pop     eax
481
        jnz     .loop
2426 mario79 482
.no_mouse_check:
2288 clevermous 483
        btr     [ebx+APPDATA.event_mask], eax
484
        jnc     .loop
485
  .result:      ; retval = eax+1
486
        inc     eax
487
        ret
488
  .BtKy:
489
        movzx   edx, bh
490
        movzx   edx, word[WIN_STACK+edx*2]
491
        je      .Keys          ; eax=1, retval Keys=2
492
.Buttons:                      ; eax=2, retval Buttons=3
493
        cmp     byte[BTN_COUNT], 0
494
        je      .loop          ; empty ???
495
        cmp     edx, [TASK_COUNT]
496
        jne     .loop          ; not Top ???
497
        mov     edx, [BTN_BUFF]
498
        shr     edx, 8
499
        cmp     edx, 0xFFFF    ;-ID for Minimize-Button of Form
500
        jne     .result
501
        mov     [window_minimize], 1
502
        dec     byte[BTN_COUNT]
503
        jmp     .loop
504
.Keys:    ; eax==1
505
        cmp     edx, [TASK_COUNT]
506
        jne     @f             ; not Top ???
507
        cmp     [KEY_COUNT], al; al==1
508
        jae     .result        ; not empty ???
509
  @@:
510
        mov     edx, hotkey_buffer
511
  @@:
512
        cmp     [edx], bh      ; bh - slot for testing
513
        je      .result
514
        add     edx, 8
515
        cmp     edx, hotkey_buffer+120*8
516
        jb      @b
517
        jmp     .loop
518
;end.