Subversion Repositories Kolibri OS

Rev

Rev 1300 | Rev 1341 | 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: 1334 $
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
251
        mov     ebx, esi
252
        lea     eax, [esi + SYS_BUTTON.sizeof]
253
        call    memmove
254
        dec     dword[edi]
255
        add     ecx, -SYS_BUTTON.sizeof
256
        jmp     .next_button
257
 
258
  .exit:
259
        ret
260
 
261
align 4
262
;------------------------------------------------------------------------------
263
check_buttons: ;///////////////////////////////////////////////////////////////
264
;------------------------------------------------------------------------------
265
; 
266
;------------------------------------------------------------------------------
267
        cmp     byte[BTN_DOWN], 0    ; mouse buttons pressed
268
        jnz     @f
269
        mov     [bPressedMouseXY_B], 0
270
        ret
271
 
272
    @@: pushad
273
        xor     esi, esi
274
        mov     edi, [BTN_ADDR]
275
        mov     edx, [edi]
276
        test    edx, edx
277
        jne     @f
278
        popad
279
        ret
280
 
281
        ;here i catch the coordinates when the mouse's button is clicked
282
    @@: push    ax
283
        cmp     [bPressedMouseXY_B], 0 ; FALSE
284
        jnz     @f
285
        mov     [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
286
        mov     ax, [MOUSE_X]
287
        mov     [mx], ax
288
        mov     ax, [MOUSE_Y]
289
        mov     [my], ax
290
    @@: pop     ax
291
        ;and it is only refreshed after the mouse's button release
292
 
293
        push    esi
294
        inc     edx
295
        push    edx
296
 
297
  .buttonnewcheck:
298
        pop     edx
299
        pop     esi
300
        inc     esi
301
        cmp     edx, esi
302
        jge     .bch
303
 
304
        popad
305
        ret
306
 
307
  .bch:
308
        push    esi
309
        push    edx
310
        mov     eax, esi
311
        shl     eax, 4
312
        add     eax, edi
313
 
314
        ; check that button is at top of windowing stack
315
        movzx   ebx, [eax + SYS_BUTTON.pslot]
316
        movzx   ecx, word[WIN_STACK + ebx * 2]
317
        cmp     ecx, [TASK_COUNT]
318
        jne     .buttonnewcheck
319
 
320
        ; check that button start is inside window x/y end
321
        shl     ebx, 5
322
 
323
        test    [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
324
        jnz     .buttonnewcheck
325
 
326
        movzx   edx, [eax + SYS_BUTTON.left]
327
        cmp     edx, [window_data + ebx + WDATA.box.width] ;ecx
328
        jge     .buttonnewcheck
329
 
330
        movzx   edx, [eax + SYS_BUTTON.top]
331
        cmp     edx, [window_data + ebx + WDATA.box.height] ;ecx
332
        jge     .buttonnewcheck
333
 
334
        ; check coordinates
335
 
336
        ; mouse x >= button x ?
337
        add     ebx, window_data
338
        mov     ecx, [ebx + WDATA.box.left]
339
        movzx   edx, [eax + SYS_BUTTON.left]
340
        add     edx, ecx
341
        mov     cx, [mx]   ;mov cx,[MOUSE_X]
342
        cmp     edx, ecx
343
        jg      .buttonnewcheck
344
 
345
        movzx   ebx, [eax + SYS_BUTTON.width]
346
        add     edx, ebx
347
        cmp     ecx, edx
348
        jg      .buttonnewcheck
349
 
350
        ; mouse y >= button y ?
351
        movzx   ebx, [eax + SYS_BUTTON.pslot]
352
        shl     ebx, 5
353
        add     ebx, window_data
354
        mov     ecx, [ebx + WDATA.box.top]
355
        movzx   edx, [eax + SYS_BUTTON.top]
356
        add     edx, ecx
357
        mov     cx, [my]  ;mov cx,[MOUSE_Y]
358
        cmp     edx, ecx
359
        jg      .buttonnewcheck
360
 
361
        movzx   ebx, [eax + SYS_BUTTON.height]
362
        add     edx, ebx
363
        cmp     ecx, edx
364
        jg      .buttonnewcheck
365
 
366
        ; mouse on button
367
 
368
        pop     edx
369
        pop     esi
370
 
371
        mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]     ; button id : bits 16-31
372
        mov     bx, [eax + SYS_BUTTON.id_lo]       ; button id : bits 00-16
373
        push    ebx
374
 
375
        mov     byte[MOUSE_DOWN], 1  ; no mouse down checks
376
        call    button._.negative_button
377
 
378
        pushad
379
        push    eax
380
        mov     al, [BTN_DOWN]
381
        mov     byte[btn_down_determ], al
382
        pop     eax
383
 
384
  .cbwaitmouseup:
385
        call    checkidle
386
        call    [draw_pointer]
387
 
388
        pushad
389
        call    stack_handler
390
        popad
391
 
392
        cmp     byte[BTN_DOWN], 0  ; mouse buttons pressed ?
393
        jnz     .cbwaitmouseup
394
        popad
395
 
396
        call    button._.negative_button
397
        mov     byte[MOUSE_BACKGROUND], 0  ; no mouse background
398
        mov     byte[DONT_DRAW_MOUSE], 0  ; draw mouse
399
 
400
        ; check coordinates
401
        pusha
402
 
403
        ; mouse x >= button x ?
404
        movzx   ebx, [eax + SYS_BUTTON.pslot]
405
        shl     ebx, 5
406
        add     ebx, window_data
407
        mov     ecx, [ebx + WDATA.box.left]
408
        movzx   edx, [eax + SYS_BUTTON.left]
409
        add     edx, ecx
410
        mov     cx, [MOUSE_X]
411
        cmp     edx, ecx
412
        jg      .no_on_button ;if we release the pointer out of the button area
413
 
414
        movzx   ebx, [eax + SYS_BUTTON.width]
415
        add     edx, ebx
416
        cmp     ecx, edx
417
        jg      .no_on_button
418
 
419
        ; mouse y >= button y ?
420
        movzx   ebx, [eax + SYS_BUTTON.pslot]
421
        shl     ebx, 5
422
        add     ebx, window_data
423
        mov     ecx, [ebx + WDATA.box.top]
424
        movzx   edx, [eax + SYS_BUTTON.top]
425
        add     edx, ecx
426
        mov     cx, [MOUSE_Y]
427
        cmp     edx, ecx
428
        jg      .no_on_button
429
 
430
        movzx   ebx, [eax + SYS_BUTTON.height]
431
        add     edx, ebx
432
        cmp     ecx, edx
433
        jg      .no_on_button
434
 
435
        popa
436
 
437
        mov     byte[BTN_COUNT], 1 ; no of buttons in buffer
438
        pop     ebx
439
        mov     [BTN_BUFF], ebx   ; lets put the button id in buffer
440
        push    ebx
441
        pusha
442
        jmp     .yes_on_button
443
 
444
  .no_on_button:
445
        mov     byte[BTN_COUNT], 0 ; no of buttons in buffer
446
 
447
  .yes_on_button:
448
        mov     byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
449
        popa
450
        pop     ebx
451
        popa
452
        ret
453
 
454
;==============================================================================
455
;///// private functions //////////////////////////////////////////////////////
456
;==============================================================================
457
 
458
;------------------------------------------------------------------------------
459
button._.dececx: ;/////////////////////////////////////////////////////////////
460
;------------------------------------------------------------------------------
461
; 
462
;------------------------------------------------------------------------------
463
        sub     cl, 0x20
464
        jnc     @f
465
        xor     cl, cl
466
    @@: sub     ch, 0x20
467
        jnc     @f
468
        xor     ch, ch
469
    @@: rol     ecx, 16
470
        sub     cl, 0x20
471
        jnc     @f
472
        xor     cl, cl
473
    @@: rol     ecx, 16
474
        ret
475
 
476
;------------------------------------------------------------------------------
477
button._.incecx: ;/////////////////////////////////////////////////////////////
478
;------------------------------------------------------------------------------
479
; 
480
;------------------------------------------------------------------------------
481
        add     cl, 0x20
482
        jnc     @f
483
        or      cl, -1
484
    @@: add     ch, 0x20
485
        jnc     @f
486
        or      ch, -1
487
    @@: rol     ecx, 16
488
        add     cl, 0x20
489
        jnc     @f
490
        or      cl, -1
491
    @@: rol     ecx, 16
492
        ret
493
 
494
;------------------------------------------------------------------------------
495
button._.incecx2: ;////////////////////////////////////////////////////////////
496
;------------------------------------------------------------------------------
497
; 
498
;------------------------------------------------------------------------------
499
        add     cl, 0x14
500
        jnc     @f
501
        or      cl, -1
502
    @@: add     ch, 0x14
503
        jnc     @f
504
        or      ch, -1
505
    @@: rol     ecx, 16
506
        add     cl, 0x14
507
        jnc     @f
508
        or      cl, -1
509
    @@: rol     ecx, 16
510
        ret
511
 
512
;------------------------------------------------------------------------------
513
button._.button_dececx: ;//////////////////////////////////////////////////////
514
;------------------------------------------------------------------------------
515
; 
516
;------------------------------------------------------------------------------
517
        cmp     [buttontype], 1
518
        jne     .finish
519
 
520
        push    eax
521
        mov     al, 1
522
        cmp     edi, 20
523
        jg      @f
524
        mov     al, 2
525
 
526
    @@: sub     cl, al
527
        jnc     @f
528
        xor     cl, cl
529
    @@: sub     ch, al
530
        jnc     @f
531
        xor     ch, ch
532
    @@: rol     ecx, 16
533
        sub     cl, al
534
        jnc     @f
535
        xor     cl, cl
536
    @@: rol     ecx, 16
537
 
538
        pop     eax
539
 
540
  .finish:
541
        ret
542
 
543
;------------------------------------------------------------------------------
544
button._.negative_button: ;////////////////////////////////////////////////////
545
;------------------------------------------------------------------------------
546
; 
547
;------------------------------------------------------------------------------
548
        ; If requested, do not display button border on press.
549
        test    ebx, 0x20000000
550
        jz      .draw_negative_button
551
        ret
552
 
553
  .draw_negative_button:
554
        pushad
555
 
556
        mov     ebx, dword[eax + SYS_BUTTON.left]
557
        mov     ecx, dword[eax + SYS_BUTTON.top]
558
        rol     ebx, 16
559
        rol     ecx, 16
560
        push    ebx ecx
561
 
562
        ; calculate window-relative coordinates
563
        shr     ebx, 16
564
        shr     ecx, 16
565
        movzx   eax, word[eax + SYS_BUTTON.pslot]
566
        shl     eax, 5
567
        add     eax, window_data
568
        add     ebx, [eax + WDATA.box.left]
569
        add     ecx, [eax + WDATA.box.top]
570
 
571
        xor     edi, edi
572
        inc     edi
573
 
574
        ; top border
575
        mov     eax, ebx
576
        shl     eax, 16
577
        mov     ax, bx
578
        add     ax, [esp + 4]
579
        mov     ebx, ecx
580
        shl     ebx, 16
581
        mov     bx, cx
582
        push    ebx
583
        mov     ecx, 0x01000000
584
        call    [draw_line]
585
 
586
        ; bottom border
587
        movzx   edx, word[esp + 4 + 0]
588
        add     ebx, edx
589
        shl     edx, 16
590
        add     ebx, edx
591
        call    [draw_line]
592
 
593
        ; left border
594
        pop     ebx
595
        push    edx
596
        mov     edx, eax
597
        shr     edx, 16
598
        mov     ax, dx
599
        mov     edx, ebx
600
        shr     edx, 16
601
        mov     bx, dx
602
        add     bx, [esp + 4 + 0]
603
        pop     edx
604
        add     ebx, 0x00010000
605
        dec     bx
606
        call    [draw_line]
607
 
608
        ; right border
609
        mov     dx, [esp + 4]
610
        add     ax, dx
611
        shl     edx, 16
612
        add     eax, edx
613
        call    [draw_line]
614
 
615
        pop     ecx ebx
616
 
617
        popad
618
        ret