Subversion Repositories Kolibri OS

Rev

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

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