Subversion Repositories Kolibri OS

Rev

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

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