Subversion Repositories Kolibri OS

Rev

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