Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1334 mikedld 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
9
$Revision: 1381 $
10
 
11
 
12
button._.MAX_BUTTONS = 4095
13
 
14
 
15
;==============================================================================
16
;///// public functions ///////////////////////////////////////////////////////
17
;==============================================================================
18
 
19
struc SYS_BUTTON
20
{
21
  .pslot  dw ?
22
  .id_lo  dw ?
23
  .left   dw ?
24
  .width  dw ?
25
  .top    dw ?
26
  .height dw ?
27
  .id_hi  dw ?
1381 diamond 28
  .align  dw ?
1334 mikedld 29
  .sizeof:
30
}
31
virtual at 0
32
  SYS_BUTTON SYS_BUTTON
33
end virtual
34
 
35
iglobal
36
  mx                dw 0x0 ; keeps the x mouse's position when it was clicked
37
  my                dw 0x0 ; keeps the y mouse's position when it was clicked
38
  bPressedMouseXY_B db 0x0
39
  btn_down_determ   db 0x0
40
endg
41
 
42
align 4
43
;------------------------------------------------------------------------------
44
syscall_button: ;///// system function 8 //////////////////////////////////////
45
;------------------------------------------------------------------------------
1362 mikedld 46
;? Define/undefine GUI button object
1334 mikedld 47
;------------------------------------------------------------------------------
1362 mikedld 48
;; Define button:
49
;> ebx = pack[16(x), 16(width)]
50
;> ecx = pack[16(y), 16(height)]
51
;> edx = pack[8(flags), 24(button identifier)]
52
;>       flags bits:
53
;>          7 (31) = 0
54
;>          6 (30) = don't draw button
55
;>          5 (29) = don't draw button frame when pressed
56
;> esi = button color
1334 mikedld 57
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1362 mikedld 58
;; Undefine button:
59
;> edx = pack[8(flags), 24(button identifier)]
60
;>       flags bits:
61
;>          7 (31) = 1
1334 mikedld 62
;------------------------------------------------------------------------------
63
        ; do we actually need to undefine the button?
64
        test    edx, 0x80000000
65
        jnz     .remove_button
66
 
67
        ; do we have free button slots available?
68
        mov     edi, [BTN_ADDR]
69
        mov     eax, [edi]
70
        cmp     eax, button._.MAX_BUTTONS
71
        jge     .exit
72
 
73
        ; does it have positive size? (otherwise it doesn't have sense)
74
        or      bx, bx
75
        jle     .exit
76
        or      cx, cx
77
        jle     .exit
78
 
79
        ; make coordinates clientbox-relative
80
        push    eax
81
        mov     eax, [current_slot]
82
        rol     ebx, 16
83
        add     bx, word[eax + APPDATA.wnd_clientbox.left]
84
        rol     ebx, 16
85
        rol     ecx, 16
86
        add     cx, word[eax + APPDATA.wnd_clientbox.top]
87
        rol     ecx, 16
88
        pop     eax
89
 
90
        ; basic checks passed, define the button
91
        push    ebx ecx edx
92
        inc     eax
93
        mov     [edi], ax
94
        shl     eax, 4
95
        add     edi, eax
96
        ; NOTE: this code doesn't rely on SYS_BUTTON struct, please revise it
97
        ;       if you change something
98
        mov     ax, [CURRENT_TASK]
99
        stosw
100
        mov     ax, dx
101
        stosw               ; button id number: bits 0-15
102
        mov     eax, ebx
103
        rol     eax, 16
104
        stosd               ; x start | x size
105
        mov     eax, ecx
106
        rol     eax, 16
107
        stosd               ; y start | y size
108
        mov     eax, edx
109
        shr     eax, 16
110
        stosw               ; button id number: bits 16-31
111
        pop     edx ecx ebx
112
 
113
        ; do we also need to draw the button?
114
        test    edx, 0x40000000
115
        jnz     .exit
116
 
117
        ; draw button body
118
 
119
        pushad
120
 
121
        ; calculate window-relative coordinates
122
        movzx   edi, cx
123
        shr     ebx, 16
124
        shr     ecx, 16
125
        mov     eax, [TASK_BASE]
126
        add     ebx, [eax - twdw + WDATA.box.left]
127
        add     ecx, [eax - twdw + WDATA.box.top]
128
        mov     eax, ebx
129
        shl     eax, 16
130
        mov     ax, bx
131
        add     ax, word[esp + 16]
132
        mov     ebx, ecx
133
        shl     ebx, 16
134
        mov     bx, cx
135
 
136
        ; calculate initial color
137
        mov     ecx, esi
138
        cmp     [buttontype], 0
139
        je      @f
140
        call    button._.incecx2
141
 
142
        ; set button height counter
143
    @@: mov     edx, edi
144
 
145
  .next_line:
146
        call    button._.button_dececx
147
        push    edi
148
        xor     edi, edi
149
        call    [draw_line]
150
        pop     edi
151
        add     ebx, 0x00010001
152
        dec     edx
153
        jnz     .next_line
154
 
155
        popad
156
 
157
        ; draw button frame
158
 
159
        push    ebx ecx
160
 
161
        ; calculate window-relative coordinates
162
        shr     ebx, 16
163
        shr     ecx, 16
164
        mov     eax, [TASK_BASE]
165
        add     ebx, [eax - twdw + WDATA.box.left]
166
        add     ecx, [eax - twdw + WDATA.box.top]
167
 
168
        ; top border
169
        mov     eax, ebx
170
        shl     eax, 16
171
        mov     ax, bx
172
        add     ax, [esp + 4]
173
        mov     ebx, ecx
174
        shl     ebx, 16
175
        mov     bx, cx
176
        push    ebx
177
        xor     edi, edi
178
        mov     ecx, esi
179
        call    button._.incecx
180
        call    [draw_line]
181
 
182
        ; bottom border
183
        movzx   edx, word[esp + 4 + 0]
184
        add     ebx, edx
185
        shl     edx, 16
186
        add     ebx, edx
187
        mov     ecx, esi
188
        call    button._.dececx
189
        call    [draw_line]
190
 
191
        ; left border
192
        pop     ebx
193
        push    edx
194
        mov     edx, eax
195
        shr     edx, 16
196
        mov     ax, dx
197
        mov     edx, ebx
198
        shr     edx, 16
199
        mov     bx, dx
200
        add     bx, [esp + 4 + 0]
201
        pop     edx
202
        mov     ecx, esi
203
        call    button._.incecx
204
        call    [draw_line]
205
 
206
        ; right border
207
        mov     dx, [esp + 4]
208
        add     ax, dx
209
        shl     edx, 16
210
        add     eax, edx
211
        add     ebx, 0x00010000
212
        mov     ecx, esi
213
        call    button._.dececx
214
        call    [draw_line]
215
 
216
        pop     ecx ebx
217
 
218
  .exit:
219
        ret
220
 
221
; FIXME: mutex needed
222
syscall_button.remove_button:
223
        and     edx, 0x00ffffff
224
        mov     edi, [BTN_ADDR]
225
        mov     ebx, [edi]
226
        inc     ebx
227
        imul    esi, ebx, SYS_BUTTON.sizeof
228
        add     esi, edi
229
        xor     ecx, ecx
230
        add     ecx, -SYS_BUTTON.sizeof
231
 
232
  .next_button:
233
        dec     ebx
234
        jz      .exit
235
 
236
        add     ecx, SYS_BUTTON.sizeof
237
        add     esi, -SYS_BUTTON.sizeof
238
 
239
        ; does it belong to our process?
240
        mov     ax, [CURRENT_TASK]
241
        cmp     ax, [esi + SYS_BUTTON.pslot]
242
        jne     .next_button
243
 
244
        ; does the identifier match?
245
        mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
246
        mov     ax, [esi + SYS_BUTTON.id_lo]
247
        and     eax, 0x00ffffff
248
        cmp     edx, eax
249
        jne     .next_button
250
 
251
        ; okay, undefine it
1341 mikedld 252
        push    ebx
1334 mikedld 253
        mov     ebx, esi
254
        lea     eax, [esi + SYS_BUTTON.sizeof]
255
        call    memmove
256
        dec     dword[edi]
257
        add     ecx, -SYS_BUTTON.sizeof
1341 mikedld 258
        pop     ebx
1334 mikedld 259
        jmp     .next_button
260
 
261
  .exit:
262
        ret
263
 
264
align 4
265
;------------------------------------------------------------------------------
266
check_buttons: ;///////////////////////////////////////////////////////////////
267
;------------------------------------------------------------------------------
1362 mikedld 268
;? 
1334 mikedld 269
;------------------------------------------------------------------------------
270
        cmp     byte[BTN_DOWN], 0    ; mouse buttons pressed
271
        jnz     @f
272
        mov     [bPressedMouseXY_B], 0
273
        ret
274
 
275
    @@: pushad
276
        xor     esi, esi
277
        mov     edi, [BTN_ADDR]
278
        mov     edx, [edi]
279
        test    edx, edx
280
        jne     @f
281
        popad
282
        ret
283
 
284
        ;here i catch the coordinates when the mouse's button is clicked
285
    @@: push    ax
286
        cmp     [bPressedMouseXY_B], 0 ; FALSE
287
        jnz     @f
288
        mov     [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
289
        mov     ax, [MOUSE_X]
290
        mov     [mx], ax
291
        mov     ax, [MOUSE_Y]
292
        mov     [my], ax
293
    @@: pop     ax
294
        ;and it is only refreshed after the mouse's button release
295
 
296
        push    esi
297
        inc     edx
298
        push    edx
299
 
300
  .buttonnewcheck:
301
        pop     edx
302
        pop     esi
303
        inc     esi
304
        cmp     edx, esi
305
        jge     .bch
306
 
307
        popad
308
        ret
309
 
310
  .bch:
311
        push    esi
312
        push    edx
313
        mov     eax, esi
314
        shl     eax, 4
315
        add     eax, edi
316
 
317
        ; check that button is at top of windowing stack
318
        movzx   ebx, [eax + SYS_BUTTON.pslot]
319
        movzx   ecx, word[WIN_STACK + ebx * 2]
320
        cmp     ecx, [TASK_COUNT]
321
        jne     .buttonnewcheck
322
 
323
        ; check that button start is inside window x/y end
324
        shl     ebx, 5
325
 
326
        test    [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
327
        jnz     .buttonnewcheck
328
 
329
        movzx   edx, [eax + SYS_BUTTON.left]
330
        cmp     edx, [window_data + ebx + WDATA.box.width] ;ecx
331
        jge     .buttonnewcheck
332
 
333
        movzx   edx, [eax + SYS_BUTTON.top]
334
        cmp     edx, [window_data + ebx + WDATA.box.height] ;ecx
335
        jge     .buttonnewcheck
336
 
337
        ; check coordinates
338
 
339
        ; mouse x >= button x ?
340
        add     ebx, window_data
341
        mov     ecx, [ebx + WDATA.box.left]
342
        movzx   edx, [eax + SYS_BUTTON.left]
343
        add     edx, ecx
344
        mov     cx, [mx]   ;mov cx,[MOUSE_X]
345
        cmp     edx, ecx
346
        jg      .buttonnewcheck
347
 
348
        movzx   ebx, [eax + SYS_BUTTON.width]
349
        add     edx, ebx
350
        cmp     ecx, edx
351
        jg      .buttonnewcheck
352
 
353
        ; mouse y >= button y ?
354
        movzx   ebx, [eax + SYS_BUTTON.pslot]
355
        shl     ebx, 5
356
        add     ebx, window_data
357
        mov     ecx, [ebx + WDATA.box.top]
358
        movzx   edx, [eax + SYS_BUTTON.top]
359
        add     edx, ecx
360
        mov     cx, [my]  ;mov cx,[MOUSE_Y]
361
        cmp     edx, ecx
362
        jg      .buttonnewcheck
363
 
364
        movzx   ebx, [eax + SYS_BUTTON.height]
365
        add     edx, ebx
366
        cmp     ecx, edx
367
        jg      .buttonnewcheck
368
 
369
        ; mouse on button
370
 
371
        pop     edx
372
        pop     esi
373
 
374
        mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]     ; button id : bits 16-31
375
        mov     bx, [eax + SYS_BUTTON.id_lo]       ; button id : bits 00-16
376
        push    ebx
377
 
378
        mov     byte[MOUSE_DOWN], 1  ; no mouse down checks
379
        call    button._.negative_button
380
 
381
        pushad
382
        push    eax
383
        mov     al, [BTN_DOWN]
384
        mov     byte[btn_down_determ], al
385
        pop     eax
386
 
387
  .cbwaitmouseup:
388
        call    checkidle
389
        call    [draw_pointer]
390
 
391
        pushad
392
        call    stack_handler
393
        popad
394
 
395
        cmp     byte[BTN_DOWN], 0  ; mouse buttons pressed ?
396
        jnz     .cbwaitmouseup
397
        popad
398
 
399
        call    button._.negative_button
400
        mov     byte[MOUSE_BACKGROUND], 0  ; no mouse background
401
        mov     byte[DONT_DRAW_MOUSE], 0  ; draw mouse
402
 
403
        ; check coordinates
404
        pusha
405
 
406
        ; mouse x >= button x ?
407
        movzx   ebx, [eax + SYS_BUTTON.pslot]
408
        shl     ebx, 5
409
        add     ebx, window_data
410
        mov     ecx, [ebx + WDATA.box.left]
411
        movzx   edx, [eax + SYS_BUTTON.left]
412
        add     edx, ecx
413
        mov     cx, [MOUSE_X]
414
        cmp     edx, ecx
415
        jg      .no_on_button ;if we release the pointer out of the button area
416
 
417
        movzx   ebx, [eax + SYS_BUTTON.width]
418
        add     edx, ebx
419
        cmp     ecx, edx
420
        jg      .no_on_button
421
 
422
        ; mouse y >= button y ?
423
        movzx   ebx, [eax + SYS_BUTTON.pslot]
424
        shl     ebx, 5
425
        add     ebx, window_data
426
        mov     ecx, [ebx + WDATA.box.top]
427
        movzx   edx, [eax + SYS_BUTTON.top]
428
        add     edx, ecx
429
        mov     cx, [MOUSE_Y]
430
        cmp     edx, ecx
431
        jg      .no_on_button
432
 
433
        movzx   ebx, [eax + SYS_BUTTON.height]
434
        add     edx, ebx
435
        cmp     ecx, edx
436
        jg      .no_on_button
437
 
438
        popa
439
 
440
        mov     byte[BTN_COUNT], 1 ; no of buttons in buffer
441
        pop     ebx
442
        mov     [BTN_BUFF], ebx   ; lets put the button id in buffer
443
        push    ebx
444
        pusha
445
        jmp     .yes_on_button
446
 
447
  .no_on_button:
448
        mov     byte[BTN_COUNT], 0 ; no of buttons in buffer
449
 
450
  .yes_on_button:
451
        mov     byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
452
        popa
453
        pop     ebx
454
        popa
455
        ret
456
 
457
;==============================================================================
458
;///// private functions //////////////////////////////////////////////////////
459
;==============================================================================
460
 
461
;------------------------------------------------------------------------------
462
button._.dececx: ;/////////////////////////////////////////////////////////////
463
;------------------------------------------------------------------------------
1362 mikedld 464
;? 
1334 mikedld 465
;------------------------------------------------------------------------------
466
        sub     cl, 0x20
467
        jnc     @f
468
        xor     cl, cl
469
    @@: sub     ch, 0x20
470
        jnc     @f
471
        xor     ch, ch
472
    @@: rol     ecx, 16
473
        sub     cl, 0x20
474
        jnc     @f
475
        xor     cl, cl
476
    @@: rol     ecx, 16
477
        ret
478
 
479
;------------------------------------------------------------------------------
480
button._.incecx: ;/////////////////////////////////////////////////////////////
481
;------------------------------------------------------------------------------
1362 mikedld 482
;? 
1334 mikedld 483
;------------------------------------------------------------------------------
484
        add     cl, 0x20
485
        jnc     @f
486
        or      cl, -1
487
    @@: add     ch, 0x20
488
        jnc     @f
489
        or      ch, -1
490
    @@: rol     ecx, 16
491
        add     cl, 0x20
492
        jnc     @f
493
        or      cl, -1
494
    @@: rol     ecx, 16
495
        ret
496
 
497
;------------------------------------------------------------------------------
498
button._.incecx2: ;////////////////////////////////////////////////////////////
499
;------------------------------------------------------------------------------
1362 mikedld 500
;? 
1334 mikedld 501
;------------------------------------------------------------------------------
502
        add     cl, 0x14
503
        jnc     @f
504
        or      cl, -1
505
    @@: add     ch, 0x14
506
        jnc     @f
507
        or      ch, -1
508
    @@: rol     ecx, 16
509
        add     cl, 0x14
510
        jnc     @f
511
        or      cl, -1
512
    @@: rol     ecx, 16
513
        ret
514
 
515
;------------------------------------------------------------------------------
516
button._.button_dececx: ;//////////////////////////////////////////////////////
517
;------------------------------------------------------------------------------
1362 mikedld 518
;? 
1334 mikedld 519
;------------------------------------------------------------------------------
520
        cmp     [buttontype], 1
521
        jne     .finish
522
 
523
        push    eax
524
        mov     al, 1
525
        cmp     edi, 20
526
        jg      @f
527
        mov     al, 2
528
 
529
    @@: sub     cl, al
530
        jnc     @f
531
        xor     cl, cl
532
    @@: sub     ch, al
533
        jnc     @f
534
        xor     ch, ch
535
    @@: rol     ecx, 16
536
        sub     cl, al
537
        jnc     @f
538
        xor     cl, cl
539
    @@: rol     ecx, 16
540
 
541
        pop     eax
542
 
543
  .finish:
544
        ret
545
 
546
;------------------------------------------------------------------------------
547
button._.negative_button: ;////////////////////////////////////////////////////
548
;------------------------------------------------------------------------------
1362 mikedld 549
;? 
1334 mikedld 550
;------------------------------------------------------------------------------
1362 mikedld 551
        ; if requested, do not display button border on press.
1334 mikedld 552
        test    ebx, 0x20000000
1362 mikedld 553
        jnz     .exit
1334 mikedld 554
 
555
        pushad
556
 
1362 mikedld 557
        xchg    esi, eax
1334 mikedld 558
 
1362 mikedld 559
        movzx   ecx, [esi + SYS_BUTTON.pslot]
560
        shl     ecx, 5
561
        add     ecx, window_data
1334 mikedld 562
 
1362 mikedld 563
        mov     eax, dword[esi + SYS_BUTTON.left]
564
        mov     ebx, dword[esi + SYS_BUTTON.top]
565
        add     eax, [ecx + WDATA.box.left]
566
        add     ebx, [ecx + WDATA.box.top]
567
        push    eax ebx
568
        pop     edx ecx
569
        rol     eax, 16
570
        rol     ebx, 16
571
        add     ax, cx
572
        add     bx, dx
1334 mikedld 573
 
1362 mikedld 574
        mov     esi, 0x01000000
575
        call    draw_rectangle.forced
1334 mikedld 576
 
1362 mikedld 577
        popad
1334 mikedld 578
 
1362 mikedld 579
  .exit:
1334 mikedld 580
        ret