Subversion Repositories Kolibri OS

Rev

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