Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1362 mikedld 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2009. 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: 1369 $
10
 
11
 
12
;==============================================================================
13
;///// public functions ///////////////////////////////////////////////////////
14
;==============================================================================
15
 
16
macro FuncTable name, [label]
17
{
18
  common
19
    align 4
20
    \label name#.ftable dword
21
  forward
22
    dd name#.#label
23
  common
24
    name#.sizeof.ftable = $ - name#.ftable
25
}
26
 
27
iglobal
28
  FuncTable syscall_display_settings, \
29
    00, 01, 02, 03, 04, 05, 06, 07, 08
30
endg
31
 
32
uglobal
33
  common_colours            rd 32
34
  new_window_starting       dd ?
35
  latest_window_touch       dd ?
36
  latest_window_touch_delta dd ?
37
  old_window_pos            BOX
38
  new_window_pos            BOX
39
  draw_limits               RECT
40
  bPressedMouseXY_W         db ?
41
  do_resize                 db ?
42
  do_resize_from_corner     db ?
43
  reposition                db ?
44
endg
45
 
46
align 4
47
;------------------------------------------------------------------------------
48
syscall_display_settings: ;///// system function 48 ///////////////////////////
49
;------------------------------------------------------------------------------
50
;; Redraw screen:
51
;< ebx = 0
52
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53
;; Set button style:
54
;< ebx = 1
55
;< ecx = 0 (flat) or 1 (with gradient)
56
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
57
;; Set system color palette:
58
;< ebx = 2
59
;< ecx = pointer to color table
60
;< edx = size of color table
61
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
62
;; Get system color palette:
63
;< ebx = 3
64
;< ecx = pointer to color table buffer
65
;< edx = size of color table buffer
66
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67
;; Get skinned caption height:
68
;< ebx = 4
69
;> eax = height in pixels
70
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71
;; Get screen working area:
72
;< ebx = 5
73
;> eax = pack[16(left), 16(right)]
74
;> ebx = pack[16(top), 16(bottom)]
75
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
76
;; Set screen working area:
77
;< ebx = 6
78
;< ecx = pack[16(left), 16(right)]
79
;< edx = pack[16(top), 16(bottom)]
80
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81
;; Get skin margins:
82
;< ebx = 7
83
;> eax = pack[16(left), 16(right)]
84
;> ebx = pack[16(top), 16(bottom)]
85
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86
;; Set skin:
87
;< ebx = 8
88
;< ecx = pointer to FileInfoBlock struct
89
;> eax = FS error code
90
;------------------------------------------------------------------------------
91
        cmp     ebx, .sizeof.ftable / 4
92
        ja      @f
93
        jmp     [.ftable + ebx * 4]
94
    @@: ret
95
 
96
 
97
align 4
98
syscall_display_settings.00:
99
        xor     eax, eax
100
        inc     ebx
101
        cmp     [windowtypechanged], ebx
102
        jne     .exit
103
        mov     [windowtypechanged], eax
104
 
105
        jmp     syscall_display_settings._.redraw_whole_screen
106
 
107
  .exit:
108
        ret
109
 
110
align 4
111
syscall_display_settings.01:
112
        and     ecx, 1
113
        cmp     ecx, [buttontype]
114
        je      .exit
115
        mov     [buttontype], ecx
116
        mov     [windowtypechanged], ebx
117
 
118
  .exit:
119
        ret
120
 
121
align 4
122
syscall_display_settings.02:
123
        dec     ebx
124
        mov     esi, ecx
125
        and     edx, 127
126
        mov     edi, common_colours
127
        mov     ecx, edx
128
        rep     movsb
129
        mov     [windowtypechanged], ebx
130
        ret
131
 
132
align 4
133
syscall_display_settings.03:
134
        mov     edi, ecx
135
        and     edx, 127
136
        mov     esi, common_colours
137
        mov     ecx, edx
138
        rep     movsb
139
        ret
140
 
141
align 4
142
syscall_display_settings.04:
143
        mov     eax, [_skinh]
144
        mov     [esp + 32], eax
145
        ret
146
 
147
align 4
148
syscall_display_settings.05:
149
        mov     eax, [screen_workarea.left - 2]
150
        mov     ax, word[screen_workarea.right]
151
        mov     [esp + 32], eax
152
        mov     eax, [screen_workarea.top - 2]
153
        mov     ax, word[screen_workarea.bottom]
154
        mov     [esp + 20], eax
155
        ret
156
 
157
align 4
158
syscall_display_settings.06:
159
        xor     esi, esi
160
 
161
        mov     edi, [Screen_Max_X]
162
        mov     eax, ecx
163
        movsx   ebx, ax
164
        sar     eax, 16
165
        cmp     eax, ebx
166
        jge     .check_horizontal
167
        inc     esi
168
        or      eax, eax
169
        jge     @f
170
        xor     eax, eax
171
    @@: mov     [screen_workarea.left], eax
172
        cmp     ebx, edi
173
        jle     @f
174
        mov     ebx, edi
175
    @@: mov     [screen_workarea.right], ebx
176
 
177
  .check_horizontal:
178
        mov     edi, [Screen_Max_Y]
179
        mov     eax, edx
180
        movsx   ebx, ax
181
        sar     eax, 16
182
        cmp     eax, ebx
183
        jge     .check_if_redraw_needed
184
        inc     esi
185
        or      eax, eax
186
        jge     @f
187
        xor     eax, eax
188
    @@: mov     [screen_workarea.top], eax
189
        cmp     ebx, edi
190
        jle     @f
191
        mov     ebx, edi
192
    @@: mov     [screen_workarea.bottom], ebx
193
 
194
  .check_if_redraw_needed:
195
        or      esi, esi
196
        jz      .exit
197
 
198
        call    repos_windows
199
        jmp     syscall_display_settings._.calculate_whole_screen
200
 
201
  .exit:
202
        ret
203
 
204
align 4
205
syscall_display_settings.07:
206
        mov     eax, [_skinmargins + 0]
207
        mov     [esp + 32], eax
208
        mov     eax, [_skinmargins + 4]
209
        mov     [esp + 20], eax
210
        ret
211
 
212
align 4
213
syscall_display_settings.08:
214
        mov     ebx, ecx
215
        call    read_skin_file
216
        mov     [esp + 32], eax
217
        test    eax, eax
218
        jnz     .exit
219
 
220
        call    syscall_display_settings._.calculate_whole_screen
221
        jmp     syscall_display_settings._.redraw_whole_screen
222
 
223
  .exit:
224
        ret
225
 
226
syscall_display_settings._.calculate_whole_screen:
227
        xor     eax, eax
228
        xor     ebx, ebx
229
        mov     ecx, [Screen_Max_X]
230
        mov     edx, [Screen_Max_Y]
231
        jmp     calculatescreen
232
 
233
syscall_display_settings._.redraw_whole_screen:
234
        xor     eax, eax
235
        mov     [draw_limits.left], eax
236
        mov     [draw_limits.top], eax
237
        mov     eax, [Screen_Max_X]
238
        mov     [draw_limits.right], eax
239
        mov     eax, [Screen_Max_Y]
240
        mov     [draw_limits.bottom], eax
241
        mov     eax, window_data
242
        jmp     redrawscreen
243
 
244
align 4
245
;------------------------------------------------------------------------------
246
syscall_set_window_shape: ;///// system function 50 ///////////////////////////
247
;------------------------------------------------------------------------------
248
;; Set window shape address:
1369 Lrz 249
;> ebx = 0
250
;> ecx = shape data address
1362 mikedld 251
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
252
;; Set window shape scale:
1369 Lrz 253
;> ebx = 1
254
;> ecx = scale power (resulting scale is 2^ebx)
1362 mikedld 255
;------------------------------------------------------------------------------
256
        mov     edi, [current_slot]
257
 
1369 Lrz 258
        test    ebx, ebx
1362 mikedld 259
        jne     .shape_scale
1369 Lrz 260
        mov     [edi + APPDATA.wnd_shape], ecx
1362 mikedld 261
 
262
  .shape_scale:
1369 Lrz 263
        dec     ebx
1362 mikedld 264
        jnz     .exit
1369 Lrz 265
        mov     [edi + APPDATA.wnd_shape_scale], ecx
1362 mikedld 266
 
267
  .exit:
268
        ret
269
 
270
align 4
271
;------------------------------------------------------------------------------
272
set_window_defaults: ;/////////////////////////////////////////////////////////
273
;------------------------------------------------------------------------------
274
;? 
275
;------------------------------------------------------------------------------
276
        push    eax ecx
277
        xor     eax, eax
278
        mov     ecx, WIN_STACK
279
    @@: inc     eax
280
        add     ecx, 2
281
        ; process no
282
        mov     [ecx + 0x000], ax
283
        ; positions in stack
284
        mov     [ecx + 0x400], ax
285
        cmp     ecx, WIN_POS - 2
286
        jne     @b
287
        pop     ecx eax
288
        ret
289
 
290
align 4
291
;------------------------------------------------------------------------------
292
calculatescreen: ;/////////////////////////////////////////////////////////////
293
;------------------------------------------------------------------------------
294
;? Scan all windows from bottom to top, calling `setscreen` for each one
295
;? intersecting given screen area
296
;------------------------------------------------------------------------------
297
;> eax = left
298
;> ebx = top
299
;> ecx = right
300
;> edx = bottom
301
;------------------------------------------------------------------------------
302
        push    esi
303
        pushfd
304
        cli
305
 
306
        mov     esi, 1
307
        call    window._.set_screen
308
 
309
        push    ebp
310
 
311
        mov     ebp, [TASK_COUNT]
312
        cmp     ebp, 1
313
        jbe     .exit
314
 
315
        push    edx ecx ebx eax
316
 
317
  .next_window:
318
        movzx   edi, word[WIN_POS + esi * 2]
319
        shl     edi, 5
320
 
321
        cmp     [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE
322
        je      .skip_window
323
 
324
        add     edi, window_data
325
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
326
        jnz     .skip_window
327
 
328
        mov     eax, [edi + WDATA.box.left]
329
        cmp     eax, [esp + RECT.right]
1368 mikedld 330
        jg      .skip_window
1362 mikedld 331
        mov     ebx, [edi + WDATA.box.top]
332
        cmp     ebx, [esp + RECT.bottom]
1368 mikedld 333
        jg      .skip_window
1362 mikedld 334
        mov     ecx, [edi + WDATA.box.width]
335
        add     ecx, eax
336
        cmp     ecx, [esp + RECT.left]
1368 mikedld 337
        jl      .skip_window
1362 mikedld 338
        mov     edx, [edi + WDATA.box.height]
339
        add     edx, ebx
340
        cmp     edx, [esp + RECT.top]
1368 mikedld 341
        jl      .skip_window
1362 mikedld 342
 
343
        cmp     eax, [esp + RECT.left]
344
        jae     @f
345
        mov     eax, [esp + RECT.left]
346
    @@: cmp     ebx, [esp + RECT.top]
347
        jae     @f
348
        mov     ebx, [esp + RECT.top]
349
    @@: cmp     ecx, [esp + RECT.right]
350
        jbe     @f
351
        mov     ecx, [esp + RECT.right]
352
    @@: cmp     edx, [esp + RECT.bottom]
353
        jbe     @f
354
        mov     edx, [esp + RECT.bottom]
355
 
356
    @@: push    esi
357
        movzx   esi, word[WIN_POS + esi * 2]
358
        call    window._.set_screen
359
        pop     esi
360
 
361
  .skip_window:
362
        inc     esi
363
        dec     ebp
364
        jnz     .next_window
365
 
366
        pop     eax ebx ecx edx
367
 
368
  .exit:
369
        pop     ebp
370
        popfd
371
        pop     esi
372
        ret
373
 
374
align 4
375
;------------------------------------------------------------------------------
376
repos_windows: ;///////////////////////////////////////////////////////////////
377
;------------------------------------------------------------------------------
378
;? 
379
;------------------------------------------------------------------------------
380
        mov     ecx, [TASK_COUNT]
381
        mov     edi, window_data + WDATA.sizeof * 2
382
        call    force_redraw_background
383
        dec     ecx
384
        jle     .exit
385
 
386
  .next_window:
387
        mov     [edi + WDATA.fl_redraw], 1
388
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
389
        jnz     .fix_maximized
390
 
391
        mov     eax, [edi + WDATA.box.left]
392
        add     eax, [edi + WDATA.box.width]
393
        mov     ebx, [Screen_Max_X]
394
        cmp     eax, ebx
395
        jle     .fix_vertical
396
        mov     eax, [edi + WDATA.box.width]
397
        sub     eax, ebx
398
        jle     @f
399
        mov     [edi + WDATA.box.width], ebx
400
    @@: sub     ebx, [edi + WDATA.box.width]
401
        mov     [edi + WDATA.box.left], ebx
402
 
403
  .fix_vertical:
404
        mov     eax, [edi + WDATA.box.top]
405
        add     eax, [edi + WDATA.box.height]
406
        mov     ebx, [Screen_Max_Y]
407
        cmp     eax, ebx
408
        jle     .fix_client_box
409
        mov     eax, [edi + WDATA.box.height]
410
        sub     eax, ebx
411
        jle     @f
412
        mov     [edi + WDATA.box.height], ebx
413
    @@: sub     ebx, [edi + WDATA.box.height]
414
        mov     [edi + WDATA.box.top], ebx
415
        jmp     .fix_client_box
416
 
417
  .fix_maximized:
418
        mov     eax, [screen_workarea.left]
419
        mov     [edi + WDATA.box.left], eax
420
        sub     eax, [screen_workarea.right]
421
        neg     eax
422
        mov     [edi + WDATA.box.width], eax
423
        mov     eax, [screen_workarea.top]
424
        mov     [edi + WDATA.box.top], eax
425
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
426
        jnz     .fix_client_box
427
        sub     eax, [screen_workarea.bottom]
428
        neg     eax
429
        mov     [edi + WDATA.box.height], eax
430
 
431
  .fix_client_box:
432
        call    set_window_clientbox
433
 
434
        add     edi, WDATA.sizeof
435
        loop    .next_window
436
 
437
  .exit:
438
        ret
439
 
440
align 4
441
;------------------------------------------------------------------------------
442
check_window_position: ;///////////////////////////////////////////////////////
443
;------------------------------------------------------------------------------
444
;? Check if window is inside screen area
445
;------------------------------------------------------------------------------
446
;> edi = pointer to WDATA
447
;------------------------------------------------------------------------------
448
        push    eax ebx ecx edx esi
449
 
450
        mov     eax, [edi + WDATA.box.left]
451
        mov     ebx, [edi + WDATA.box.top]
452
        mov     ecx, [edi + WDATA.box.width]
453
        mov     edx, [edi + WDATA.box.height]
454
 
455
        mov     esi, [Screen_Max_X]
456
        cmp     ecx, esi
1368 mikedld 457
        ja      .fix_width
1362 mikedld 458
 
459
  .check_left:
460
        or      eax, eax
1368 mikedld 461
        jl      .fix_left_low
462
        add     eax, ecx
1362 mikedld 463
        cmp     eax, esi
1368 mikedld 464
        jg      .fix_left_high
1362 mikedld 465
 
466
  .check_height:
467
        mov     esi, [Screen_Max_Y]
468
        cmp     edx, esi
1368 mikedld 469
        ja      .fix_height
1362 mikedld 470
 
471
  .check_top:
472
        or      ebx, ebx
1368 mikedld 473
        jl      .fix_top_low
474
        add     ebx, edx
1362 mikedld 475
        cmp     ebx, esi
1368 mikedld 476
        jg      .fix_top_high
1362 mikedld 477
 
478
  .exit:
479
        pop     esi edx ecx ebx eax
480
        ret
481
 
1368 mikedld 482
  .fix_width:
483
        mov     ecx, esi
484
        mov     [edi + WDATA.box.width], esi
485
        jmp     .check_left
486
 
487
  .fix_left_low:
488
        xor     eax, eax
489
        mov     [edi + WDATA.box.left], eax
490
        jmp     .check_height
491
 
492
  .fix_left_high:
493
        mov     eax, esi
494
        sub     eax, ecx
495
        mov     [edi + WDATA.box.left], eax
496
        jmp     .check_height
497
 
498
  .fix_height:
499
        mov     edx, esi
500
        mov     [edi + WDATA.box.height], esi
501
        jmp     .check_top
502
 
503
  .fix_top_low:
504
        xor     ebx, ebx
505
        mov     [edi + WDATA.box.top], ebx
506
        jmp     .exit
507
 
508
  .fix_top_high:
509
        mov     ebx, esi
510
        sub     ebx, edx
511
        mov     [edi + WDATA.box.top], ebx
512
        jmp     .exit
513
 
1362 mikedld 514
align 4
515
;------------------------------------------------------------------------------
516
sys_window_mouse: ;////////////////////////////////////////////////////////////
517
;------------------------------------------------------------------------------
518
;? 
519
;------------------------------------------------------------------------------
520
        push    eax
521
 
522
        mov     eax, [timer_ticks]
523
        cmp     [new_window_starting], eax
524
        jb      .exit
525
 
526
        mov     byte[MOUSE_BACKGROUND], 0
527
        mov     byte[DONT_DRAW_MOUSE], 0
528
 
529
        mov     [new_window_starting], eax
530
 
531
  .exit:
532
        pop     eax
533
        ret
534
 
535
align 4
536
;------------------------------------------------------------------------------
537
draw_rectangle: ;//////////////////////////////////////////////////////////////
538
;------------------------------------------------------------------------------
539
;> eax = pack[16(left), 16(right)]
540
;> ebx = pack[16(top), 16(bottom)]
541
;> esi = color
542
;------------------------------------------------------------------------------
543
        push    eax ebx ecx edi
544
 
545
        xor     edi, edi
546
 
547
  .flags_set:
548
        push    ebx
549
 
550
        ; set line color
551
        mov     ecx, esi
552
 
553
        ; draw top border
554
        rol     ebx, 16
555
        push    ebx
556
        rol     ebx, 16
557
        pop     bx
558
        call    [draw_line]
559
 
560
        ; draw bottom border
561
        mov     ebx, [esp - 2]
562
        pop     bx
563
        call    [draw_line]
564
 
565
        pop     ebx
566
        add     ebx, 1 * 65536 - 1
567
 
568
        ; draw left border
569
        rol     eax, 16
570
        push    eax
571
        rol     eax, 16
572
        pop     ax
573
        call    [draw_line]
574
 
575
        ; draw right border
576
        mov     eax, [esp - 2]
577
        pop     ax
578
        call    [draw_line]
579
 
580
        pop     edi ecx ebx eax
581
        ret
582
 
583
  .forced:
584
        push    eax ebx ecx edi
585
        xor     edi, edi
586
        inc     edi
587
        jmp     .flags_set
588
 
589
align 4
590
;------------------------------------------------------------------------------
591
drawwindow_I_caption: ;////////////////////////////////////////////////////////
592
;------------------------------------------------------------------------------
593
;? 
594
;------------------------------------------------------------------------------
595
        push    [edx + WDATA.cl_titlebar]
596
        mov     esi, edx
597
 
598
        mov     edx, [esi + WDATA.box.top]
599
        mov     eax, edx
600
        lea     ebx, [edx + 21]
601
        inc     edx
602
        add     eax, [esi + WDATA.box.height]
603
 
604
        cmp     ebx, eax
605
        jbe     @f
606
        mov     ebx, eax
607
    @@: push    ebx
608
 
609
        xor     edi, edi
610
 
611
  .next_line:
612
        mov     ebx, edx
613
        shl     ebx, 16
614
        add     ebx, edx
615
        mov     eax, [esi + WDATA.box.left]
616
        inc     eax
617
        shl     eax, 16
618
        add     eax, [esi + WDATA.box.left]
619
        add     eax, [esi + WDATA.box.width]
620
        dec     eax
621
        mov     ecx, [esi + WDATA.cl_titlebar]
622
        test    ecx, 0x80000000
623
        jz      @f
624
        sub     ecx, 0x00040404
625
        mov     [esi + WDATA.cl_titlebar], ecx
626
    @@: and     ecx, 0x00ffffff
627
        call    [draw_line]
628
        inc     edx
629
        cmp     edx, [esp]
630
        jb      .next_line
631
 
632
        add     esp, 4
633
        pop     [esi + WDATA.cl_titlebar]
634
        ret
635
 
636
align 4
637
;------------------------------------------------------------------------------
638
drawwindow_I: ;////////////////////////////////////////////////////////////////
639
;------------------------------------------------------------------------------
640
;? 
641
;------------------------------------------------------------------------------
642
        pushad
643
 
644
        ; window border
645
 
646
        mov     eax, [edx + WDATA.box.left - 2]
647
        mov     ax, word[edx + WDATA.box.left]
648
        add     ax, word[edx + WDATA.box.width]
649
        mov     ebx, [edx + WDATA.box.top - 2]
650
        mov     bx, word[edx + WDATA.box.top]
651
        add     bx, word[edx + WDATA.box.height]
652
 
653
        mov     esi, [edx + WDATA.cl_frames]
654
        call    draw_rectangle
655
 
656
        ; window caption
657
 
658
        call    drawwindow_I_caption
659
 
660
        ; window client area
661
 
662
        ; do we need to draw it?
663
        mov     edi, [esi + WDATA.cl_workarea]
664
        test    edi, 0x40000000
665
        jnz     .exit
666
 
667
        ; does client area have a positive size on screen?
668
        mov     edx, [esi + WDATA.box.top]
669
        add     edx, 21 + 5
670
        mov     ebx, [esi + WDATA.box.top]
671
        add     ebx, [esi + WDATA.box.height]
672
        cmp     edx, ebx
673
        jg      .exit
674
 
675
        ; okay, let's draw it
676
        mov     eax, 1
677
        mov     ebx, 21
678
        mov     ecx, [esi + WDATA.box.width]
679
        mov     edx, [esi + WDATA.box.height]
680
        call    [drawbar]
681
 
682
  .exit:
683
        popad
684
        ret
685
 
686
align 4
687
;------------------------------------------------------------------------------
688
drawwindow_III_caption: ;/////////////////////////////////////////////////////
689
;------------------------------------------------------------------------------
690
;? 
691
;------------------------------------------------------------------------------
692
        mov     ecx, [edx + WDATA.cl_titlebar]
693
        push    ecx
694
        mov     esi, edx
695
        mov     edx, [esi + WDATA.box.top]
696
        add     edx, 4
697
        mov     ebx, [esi + WDATA.box.top]
698
        add     ebx, 20
699
        mov     eax, [esi + WDATA.box.top]
700
        add     eax, [esi + WDATA.box.height]
701
 
702
        cmp     ebx, eax
703
        jb      @f
704
        mov     ebx, eax
705
    @@: push    ebx
706
 
707
        xor     edi, edi
708
 
709
  .next_line:
710
        mov     ebx, edx
711
        shl     ebx, 16
712
        add     ebx, edx
713
        mov     eax, [esi + WDATA.box.left]
714
        shl     eax, 16
715
        add     eax, [esi + WDATA.box.left]
716
        add     eax, [esi + WDATA.box.width]
717
        add     eax, 4 * 65536 - 4
718
        mov     ecx, [esi + WDATA.cl_titlebar]
719
        test    ecx, 0x40000000
720
        jz      @f
721
        add     ecx, 0x00040404
722
    @@: test    ecx, 0x80000000
723
        jz      @f
724
        sub     ecx, 0x00040404
725
    @@: mov     [esi + WDATA.cl_titlebar], ecx
726
        and     ecx, 0x00ffffff
727
        call    [draw_line]
728
        inc     edx
729
        cmp     edx, [esp]
730
        jb      .next_line
731
 
732
        add     esp, 4
733
        pop     [esi + WDATA.cl_titlebar]
734
        ret
735
 
736
align 4
737
;------------------------------------------------------------------------------
738
drawwindow_III: ;//////////////////////////////////////////////////////////////
739
;------------------------------------------------------------------------------
740
;? 
741
;------------------------------------------------------------------------------
742
        pushad
743
 
744
        ; window border
745
 
746
        mov     eax, [edx + WDATA.box.left - 2]
747
        mov     ax, word[edx + WDATA.box.left]
748
        add     ax, word[edx + WDATA.box.width]
749
        mov     ebx, [edx + WDATA.box.top - 2]
750
        mov     bx, word[edx + WDATA.box.top]
751
        add     bx, word[edx + WDATA.box.height]
752
 
753
        mov     esi, [edx + WDATA.cl_frames]
754
        shr     esi, 1
755
        and     esi, 0x007f7f7f
756
        call    draw_rectangle
757
 
758
        push    esi
759
        mov     ecx, 3
760
        mov     esi, [edx + WDATA.cl_frames]
761
 
762
  .next_frame:
763
        add     eax, 1 * 65536 - 1
764
        add     ebx, 1 * 65536 - 1
765
        call    draw_rectangle
766
        dec     ecx
767
        jnz     .next_frame
768
 
769
        pop     esi
770
        add     eax, 1 * 65536 - 1
771
        add     ebx, 1 * 65536 - 1
772
        call    draw_rectangle
773
 
774
        ; window caption
775
 
776
        call    drawwindow_III_caption
777
 
778
        ; window client area
779
 
780
        ; do we need to draw it?
781
        mov     edi, [esi + WDATA.cl_workarea]
782
        test    edi, 0x40000000
783
        jnz     .exit
784
 
785
        ; does client area have a positive size on screen?
786
        mov     edx, [esi + WDATA.box.top]
787
        add     edx, 21 + 5
788
        mov     ebx, [esi + WDATA.box.top]
789
        add     ebx, [esi + WDATA.box.height]
790
        cmp     edx, ebx
791
        jg      .exit
792
 
793
        ; okay, let's draw it
794
        mov     eax, 5
795
        mov     ebx, 20
796
        mov     ecx, [esi + WDATA.box.width]
797
        mov     edx, [esi + WDATA.box.height]
798
        sub     ecx, 4
799
        sub     edx, 4
800
        call    [drawbar]
801
 
802
  .exit:
803
        popad
804
        ret
805
 
806
align 4
807
;------------------------------------------------------------------------------
808
waredraw: ;////////////////////////////////////////////////////////////////////
809
;------------------------------------------------------------------------------
810
;? Activate window, redrawing if necessary
811
;------------------------------------------------------------------------------
812
        ; is it overlapped by another window now?
813
        push    ecx
814
        call    window._.check_window_draw
815
        test    ecx, ecx
816
        pop     ecx
817
        jz      .do_not_draw
818
 
819
        ; yes it is, activate and update screen buffer
820
        mov     byte[MOUSE_DOWN], 1
821
        call    window._.window_activate
822
 
823
        pushad
824
        mov     edi, [TASK_COUNT]
825
        movzx   esi, word[WIN_POS + edi * 2]
826
        shl     esi, 5
827
        add     esi, window_data
828
 
829
        mov     eax, [esi + WDATA.box.left]
830
        mov     ebx, [esi + WDATA.box.top]
831
        mov     ecx, [esi + WDATA.box.width]
832
        mov     edx, [esi + WDATA.box.height]
833
 
834
        add     ecx, eax
835
        add     edx, ebx
836
 
837
        mov     edi, [TASK_COUNT]
838
        movzx   esi, word[WIN_POS + edi * 2]
839
        call    window._.set_screen
840
        popad
841
 
842
        ; tell application to redraw itself
843
        mov     [edi + WDATA.fl_redraw], 1
844
        mov     byte[MOUSE_DOWN], 0
845
        ret
846
 
847
  .do_not_draw:
848
        ; no it's not, just activate the window
849
        call    window._.window_activate
850
        mov     byte[MOUSE_DOWN], 0
851
        mov     byte[MOUSE_BACKGROUND], 0
852
        mov     byte[DONT_DRAW_MOUSE], 0
853
        ret
854
 
855
align 4
856
;------------------------------------------------------------------------------
857
minimize_window: ;/////////////////////////////////////////////////////////////
858
;------------------------------------------------------------------------------
859
;> eax = window number on screen
860
;------------------------------------------------------------------------------
861
;# corrupts [dl*]
862
;------------------------------------------------------------------------------
863
        push    edi
864
        pushfd
865
        cli
866
 
867
        ; is it already minimized?
868
        movzx   edi, word[WIN_POS + eax * 2]
869
        shl     edi, 5
870
        add     edi, window_data
871
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
872
        jnz     .exit
873
 
874
        push    eax ebx ecx edx esi
875
 
876
        ; no it's not, let's do that
877
        or      [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
878
        mov     eax, [edi + WDATA.box.left]
879
        mov     [draw_limits.left], eax
880
        mov     ecx, eax
881
        add     ecx, [edi + WDATA.box.width]
882
        mov     [draw_limits.right], ecx
883
        mov     ebx, [edi + WDATA.box.top]
884
        mov     [draw_limits.top], ebx
885
        mov     edx, ebx
886
        add     edx, [edi + WDATA.box.height]
887
        mov     [draw_limits.bottom], edx
888
        call    calculatescreen
889
        xor     esi, esi
890
        xor     eax, eax
891
        call    redrawscreen
892
 
893
        pop     esi edx ecx ebx eax
894
 
895
  .exit:
896
        popfd
897
        pop     edi
898
        ret
899
 
900
align 4
901
;------------------------------------------------------------------------------
902
restore_minimized_window: ;////////////////////////////////////////////////////
903
;------------------------------------------------------------------------------
904
;> eax = window number on screen
905
;------------------------------------------------------------------------------
906
;# corrupts [dl*]
907
;------------------------------------------------------------------------------
908
        pushad
909
        pushfd
910
        cli
911
 
912
        ; is it already restored?
913
        movzx   esi, word[WIN_POS + eax * 2]
914
        mov     edi, esi
915
        shl     edi, 5
916
        add     edi, window_data
917
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
918
        jz      .exit
919
 
920
        ; no it's not, let's do that
921
        mov     [edi + WDATA.fl_redraw], 1
922
        and     [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
923
        mov     ebp, window._.set_screen
924
        cmp     eax, [TASK_COUNT]
925
        jz      @f
926
        mov     ebp, calculatescreen
927
    @@: mov     eax, [edi + WDATA.box.left]
928
        mov     ebx, [edi + WDATA.box.top]
929
        mov     ecx, [edi + WDATA.box.width]
930
        mov     edx, [edi + WDATA.box.height]
931
        add     ecx, eax
932
        add     edx, ebx
933
        call    ebp
934
 
935
        mov     byte[MOUSE_BACKGROUND], 0
936
 
937
  .exit:
938
        popfd
939
        popad
940
        ret
941
 
942
align 4
943
;------------------------------------------------------------------------------
944
checkwindows: ;////////////////////////////////////////////////////////////////
945
;------------------------------------------------------------------------------
946
;? Check for user-initiated window operations
947
;------------------------------------------------------------------------------
948
        pushad
949
 
950
        ; do we have window minimize/restore request?
951
        cmp     [window_minimize], 0
952
        je      .check_for_mouse_buttons_state
953
 
954
        ; okay, minimize or restore top-most window and exit
955
        mov     eax, [TASK_COUNT]
956
        mov     bl, 0
957
        xchg    [window_minimize], bl
958
        dec     bl
959
        jnz     @f
960
        call    minimize_window
961
        jmp     .check_for_mouse_buttons_state
962
    @@: call    restore_minimized_window
963
 
964
  .check_for_mouse_buttons_state:
965
        ; do we have any mouse buttons pressed?
966
        cmp     byte[BTN_DOWN], 0
967
        jne     .mouse_buttons_pressed
968
 
969
        mov     [bPressedMouseXY_W], 0
970
        jmp     .exit
971
 
972
  .mouse_buttons_pressed:
973
        ; yes we do, iterate and ...
974
        mov     esi, [TASK_COUNT]
975
        inc     esi
976
 
977
        cmp     [bPressedMouseXY_W], 1
978
        ja      .next_window
979
        inc     [bPressedMouseXY_W]
980
        jnc     .next_window
981
        push    dword[MOUSE_X]
982
        pop     dword[mx]
983
 
984
  .next_window:
985
        cmp     esi, 2
986
        jb      .exit
987
 
988
        dec     esi
989
 
990
        ; is that window not minimized?
991
        movzx   edi, word[WIN_POS + esi * 2]
992
        shl     edi, 5
993
        add     edi, window_data
994
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
995
        jnz     .next_window
996
 
997
        movzx   eax, [mx]
998
        movzx   ebx, [my]
999
 
1000
        ; is the cursor inside screen bounds of that window?
1001
        mov     ecx, [edi + WDATA.box.left]
1002
        mov     edx, [edi + WDATA.box.top]
1003
        cmp     eax, ecx
1004
        jl      .next_window
1005
        cmp     ebx, edx
1006
        jl      .next_window
1007
        add     ecx, [edi + WDATA.box.width]
1008
        add     edx, [edi + WDATA.box.height]
1009
        cmp     eax, ecx
1010
        jge     .next_window
1011
        cmp     ebx, edx
1012
        jge     .next_window
1013
 
1014
        ; is that a top-most (which means active) window?
1015
        cmp     esi, [TASK_COUNT]
1016
        je      .check_for_moving_or_resizing
1017
 
1018
        ; no it's not, did we just press mouse button down above it or was it
1019
        ; already pressed before?
1020
        cmp     [bPressedMouseXY_W], 1
1021
        ja      .exit
1022
 
1023
        ; okay, we just pressed the button, activate this window and exit
1024
        lea     esi, [WIN_POS + esi * 2]
1025
        call    waredraw
1026
        jmp     .exit
1027
 
1028
  .check_for_moving_or_resizing:
1029
        ; is that window movable?
1030
        test    byte[edi + WDATA.cl_titlebar + 3], 0x01
1031
        jnz     .exit
1032
 
1033
        ; yes it is, is it rolled up?
1034
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1035
        jnz     .check_for_cursor_on_caption
1036
 
1037
        ; no it's not, can it be resized then?
1038
        mov     [do_resize_from_corner], 0
1039
        mov     dl, [edi + WDATA.fl_wstyle]
1040
        and     dl, 0x0f
1041
        cmp     dl, 0x00
1042
        je      .check_for_cursor_on_caption
1043
        cmp     dl, 0x01
1044
        je      .check_for_cursor_on_caption
1045
        cmp     dl, 0x04
1046
        je      .check_for_cursor_on_caption
1047
 
1048
        ; are we going to resize it?
1049
        mov     edx, [edi + WDATA.box.top]
1050
        add     edx, [edi + WDATA.box.height]
1051
        sub     edx, 6
1052
        cmp     ebx, edx
1053
        jl      .check_for_cursor_on_caption
1054
 
1055
        ; yes we do, remember that
1056
        mov     [do_resize_from_corner], 1
1057
        jmp     .set_move_resize_flag
1058
 
1059
  .check_for_cursor_on_caption:
1060
        ; is the cursor inside window titlebar?
1061
        push    eax
1062
        call    window._.get_titlebar_height
1063
        add     eax, [edi + WDATA.box.top]
1064
        cmp     ebx, eax
1065
        pop     eax
1066
        jge     .exit
1067
 
1068
        ; calculate duration between two clicks
1069
        mov     ecx, [timer_ticks]
1070
        mov     edx, ecx
1071
        sub     edx, [latest_window_touch]
1072
        mov     [latest_window_touch], ecx
1073
        mov     [latest_window_touch_delta], edx
1074
 
1075
  .set_move_resize_flag:
1076
        mov     cl, [BTN_DOWN]
1077
        mov     [do_resize], cl
1078
 
1079
        mov     ecx, [edi + WDATA.box.left]
1080
        mov     edx, [edi + WDATA.box.top]
1081
 
1082
        push    ecx edx
1083
        mov     [draw_limits.left], ecx
1084
        mov     [draw_limits.top], edx
1085
        add     ecx, [edi + WDATA.box.width]
1086
        add     edx, [edi + WDATA.box.height]
1087
        mov     [draw_limits.right], ecx
1088
        mov     [draw_limits.bottom], edx
1089
        pop     edx ecx
1090
 
1091
        ; calculate window-relative cursor coordinates
1092
        sub     eax, ecx
1093
        sub     ebx, edx
1094
 
1095
        push    dword[MOUSE_X]
1096
        pop     dword[WIN_TEMP_XY]
1097
 
1098
        ; save old window coordinates
1099
        push    eax
1100
        mov     eax, [edi + WDATA.box.left]
1101
        mov     [old_window_pos.left], eax
1102
        mov     [new_window_pos.left], eax
1103
        mov     eax, [edi + WDATA.box.top]
1104
        mov     [old_window_pos.top], eax
1105
        mov     [new_window_pos.top], eax
1106
        mov     eax, [edi + WDATA.box.width]
1107
        mov     [old_window_pos.width], eax
1108
        mov     [new_window_pos.width], eax
1109
        mov     eax, [edi + WDATA.box.height]
1110
        mov     [old_window_pos.height], eax
1111
        mov     [new_window_pos.height], eax
1112
        pop     eax
1113
 
1114
        ; draw negative moving/sizing frame
1115
        call    window._.draw_window_frames
1116
 
1117
        mov     [reposition], 0
1118
        mov     byte[MOUSE_DOWN], 1
1119
 
1120
  .next_mouse_state_check:
1121
        ; process OS events
1122
        mov     byte[DONT_DRAW_MOUSE], 1
1123
        call    checkidle
1124
        call    checkVga_N13
1125
        mov     byte[MOUSE_BACKGROUND], 0
1126
        call    [draw_pointer]
1127
        pushad
1128
        call    stack_handler
1129
        popad
1130
 
1131
        ; did cursor position change?
1132
        mov     esi, [WIN_TEMP_XY]
1133
        cmp     esi, [MOUSE_X]
1134
        je      .check_for_new_mouse_buttons_state
1135
 
1136
        ; yes it did, calculate window-relative cursor coordinates
1137
        movzx   ecx, word[MOUSE_X]
1138
        movzx   edx, word[MOUSE_Y]
1139
        sub     ecx, eax
1140
        sub     edx, ebx
1141
 
1142
        push    eax ebx
1143
 
1144
        ; we're going to draw new frame, erasing the old one
1145
        call    window._.draw_window_frames
1146
 
1147
        ; are we moving it right now?
1148
        cmp     [do_resize_from_corner], 0
1149
        jne     .resize_window
1150
 
1151
        ; yes we do, check if it's inside the screen area
1152
        mov     eax, [Screen_Max_X]
1153
        mov     ebx, [Screen_Max_Y]
1154
 
1155
        mov     [new_window_pos.left], 0
1156
        or      ecx, ecx
1157
        jle     .check_for_new_vert_cursor_pos
1158
        mov     [reposition], 1
1159
        sub     eax, [new_window_pos.width]
1160
        mov     [new_window_pos.left], eax
1161
        cmp     ecx, eax
1162
        jge     .check_for_new_vert_cursor_pos
1163
        mov     [new_window_pos.left], ecx
1164
 
1165
  .check_for_new_vert_cursor_pos:
1166
        mov     [new_window_pos.top], 0
1167
        or      edx, edx
1168
        jle     .draw_new_window_frame
1169
        mov     [reposition], 1
1170
        sub     ebx, [new_window_pos.height]
1171
        mov     [new_window_pos.top], ebx
1172
        cmp     edx, ebx
1173
        jge     .draw_new_window_frame
1174
        mov     [new_window_pos.top], edx
1175
        jmp     .draw_new_window_frame
1176
 
1177
  .resize_window:
1178
        push    eax ebx edx
1179
 
1180
        mov     edx, edi
1181
        sub     edx, window_data
1182
        lea     edx, [SLOT_BASE + edx * 8]
1183
 
1184
        movzx   eax, word[MOUSE_X]
1185
        cmp     eax, [edi + WDATA.box.left]
1186
        jb      .fix_new_vert_size
1187
        sub     eax, [edi + WDATA.box.left]
1188
        cmp     eax, 32
1189
        jge     @f
1190
        mov     eax, 32
1191
    @@: mov     [new_window_pos.width], eax
1192
 
1193
  .fix_new_vert_size:
1194
        call    window._.get_rolledup_height
1195
        mov     ebx, eax
1196
        movzx   eax, word[MOUSE_Y]
1197
        cmp     eax, [edi + WDATA.box.top]
1198
        jb      .set_reposition_flag
1199
        sub     eax, [edi + WDATA.box.top]
1200
        cmp     eax, ebx
1201
        jge     @f
1202
        mov     eax, ebx
1203
    @@: mov     [new_window_pos.height], eax
1204
 
1205
  .set_reposition_flag:
1206
        mov     [reposition], 1
1207
 
1208
        pop     edx ebx eax
1209
 
1210
  .draw_new_window_frame:
1211
        pop     ebx eax
1212
 
1213
        ; draw new window moving/sizing frame
1214
        call    window._.draw_window_frames
1215
 
1216
        mov     esi, [MOUSE_X]
1217
        mov     [WIN_TEMP_XY], esi
1218
 
1219
  .check_for_new_mouse_buttons_state:
1220
        ; did user release mouse button(s)?
1221
        cmp     byte[BTN_DOWN], 0
1222
        jne     .next_mouse_state_check
1223
 
1224
        ; yes he did, moving/sizing is over
1225
        mov     byte[DONT_DRAW_MOUSE], 1
1226
        mov     cl, 0
1227
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1228
        jnz     .check_other_actions
1229
 
1230
        mov     cl, [reposition]
1231
 
1232
        ; draw negative frame once again to hide it
1233
        call    window._.draw_window_frames
1234
 
1235
        ; save new window bounds
1236
        mov     eax, [new_window_pos.left]
1237
        mov     [edi + WDATA.box.left], eax
1238
        mov     eax, [new_window_pos.top]
1239
        mov     [edi + WDATA.box.top], eax
1240
        mov     eax, [new_window_pos.width]
1241
        mov     [edi + WDATA.box.width], eax
1242
        mov     eax, [new_window_pos.height]
1243
        mov     [edi + WDATA.box.height], eax
1244
        call    set_window_clientbox
1245
 
1246
        cmp     cl, 1
1247
        jne     .check_other_actions
1248
        push    esi edi ecx
1249
        mov     esi, edi
1250
        mov     ecx, 2
1251
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED
1252
        jnz     @f
1253
        add     ecx, 2
1254
    @@: sub     edi, window_data
1255
        shr     edi, 5
1256
        shl     edi, 8
1257
        add     edi, SLOT_BASE + APPDATA.saved_box
1258
        cld
1259
        rep     movsd
1260
        pop     ecx edi esi
1261
 
1262
  .check_other_actions:
1263
        mov     [reposition], cl
1264
 
1265
        pushad
1266
 
1267
        mov     dl, [edi + WDATA.fl_wstyle]
1268
        and     dl, 0x0f
1269
        cmp     dl, 0x00
1270
        je      .check_if_window_fits_screen
1271
        cmp     dl, 0x01
1272
        je      .check_if_window_fits_screen
1273
 
1274
        cmp     cl, 1
1275
        je      .no_window_sizing
1276
        mov     edx, edi
1277
        sub     edx, window_data
1278
        shr     edx, 5
1279
        shl     edx, 8
1280
        add     edx, SLOT_BASE
1281
 
1282
        ; did we right-click on titlebar?
1283
        cmp     [do_resize], 2
1284
        jne     .check_maximization_request
1285
 
1286
        ; yes we did, toggle normal/rolled up window state
1287
        xor     [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1288
        mov     [reposition], 1
1289
 
1290
        ; calculate and set appropriate window height
1291
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1292
        jz      @f
1293
        call    window._.get_rolledup_height
1294
        jmp     .set_new_window_height
1295
    @@: mov     eax, [edx + APPDATA.saved_box.height]
1296
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1297
        jz      .set_new_window_height
1298
        mov     eax, [screen_workarea.bottom]
1299
        sub     eax, [screen_workarea.top]
1300
 
1301
  .set_new_window_height:
1302
        mov     [edi + WDATA.box.height], eax
1303
        add     eax, [edi + WDATA.box.top]
1304
        cmp     eax, [Screen_Max_Y]
1305
        jbe     @f
1306
        mov     eax, [Screen_Max_Y]
1307
        sub     eax, [edi + WDATA.box.height]
1308
        mov     [edi + WDATA.box.top], eax
1309
    @@: call    check_window_position
1310
        call    set_window_clientbox
1311
 
1312
  .check_maximization_request:
1313
        ; can window change its height?
1314
        push    edx
1315
        mov     dl, [edi + WDATA.fl_wstyle]
1316
        and     dl, 0x0f
1317
        cmp     dl, 0x04
1318
        pop     edx
1319
        je      .check_if_window_fits_screen
1320
 
1321
        ; was it really a maximize/restore request?
1322
        cmp     [do_resize], 1
1323
        jne     .check_if_window_fits_screen
1324
        cmp     [do_resize_from_corner], 0
1325
        jne     .check_if_window_fits_screen
1326
        cmp     [latest_window_touch_delta], 50
1327
        jg      .check_if_window_fits_screen
1328
 
1329
        ; yes is was, toggle normal/maximized window state
1330
        xor     [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1331
        mov     [reposition], 1
1332
 
1333
        ; calculate and set appropriate window bounds
1334
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1335
        jz      .restore_normal_window_size
1336
        mov     eax, [screen_workarea.left]
1337
        mov     [edi + WDATA.box.left], eax
1338
        sub     eax, [screen_workarea.right]
1339
        neg     eax
1340
        mov     [edi + WDATA.box.width], eax
1341
        mov     eax, [screen_workarea.top]
1342
        mov     [edi + WDATA.box.top], eax
1343
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1344
        jnz     .calculate_window_client_area
1345
        sub     eax, [screen_workarea.bottom]
1346
        neg     eax
1347
        mov     [edi + WDATA.box.height], eax
1348
        jmp     .calculate_window_client_area
1349
 
1350
  .restore_normal_window_size:
1351
        push    [edi + WDATA.box.height]
1352
        push    edi
1353
        lea     esi, [edx + APPDATA.saved_box]
1354
        mov     ecx, 4
1355
        cld
1356
        rep     movsd
1357
        pop     edi
1358
        pop     eax
1359
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1360
        jz      .calculate_window_client_area
1361
        mov     [edi + WDATA.box.height], eax
1362
 
1363
  .calculate_window_client_area:
1364
        call    set_window_clientbox
1365
 
1366
  .check_if_window_fits_screen:
1367
        ; does window fit into screen area?
1368
        mov     eax, [edi + WDATA.box.top]
1369
        add     eax, [edi + WDATA.box.height]
1370
        cmp     eax, [Screen_Max_Y]
1371
        jbe     .no_window_sizing
1372
        mov     eax, [edi + WDATA.box.left]
1373
        add     eax, [edi + WDATA.box.width]
1374
        cmp     eax, [Screen_Max_X]
1375
        jbe     .no_window_sizing
1376
 
1377
        ; no it doesn't, fix that
1378
        mov     eax, [Screen_Max_X]
1379
        sub     eax, [edi + WDATA.box.width]
1380
        mov     [edi + WDATA.box.left], eax
1381
        mov     eax, [Screen_Max_Y]
1382
        sub     eax, [edi + WDATA.box.height]
1383
        mov     [edi + WDATA.box.top], eax
1384
        call    set_window_clientbox
1385
 
1386
  .no_window_sizing:
1387
        popad
1388
 
1389
        ; did somethins actually change its place?
1390
        cmp     [reposition], 0
1391
        je      .reset_vars
1392
 
1393
        mov     byte[DONT_DRAW_MOUSE], 1
1394
 
1395
        push    eax ebx ecx edx
1396
 
1397
        ; recalculate screen buffer at new position
1398
        mov     eax, [edi + WDATA.box.left]
1399
        mov     ebx, [edi + WDATA.box.top]
1400
        mov     ecx, [edi + WDATA.box.width]
1401
        mov     edx, [edi + WDATA.box.height]
1402
        add     ecx, eax
1403
        add     edx, ebx
1404
        call    calculatescreen
1405
 
1406
        ; recalculate screen buffer at old position
1407
        mov     eax, [old_window_pos.left]
1408
        mov     ebx, [old_window_pos.top]
1409
        mov     ecx, [old_window_pos.width]
1410
        mov     edx, [old_window_pos.height]
1411
        add     ecx, eax
1412
        add     edx, ebx
1413
        call    calculatescreen
1414
 
1415
        pop     edx ecx ebx eax
1416
 
1417
        mov     eax, edi
1418
        call    redrawscreen
1419
 
1420
        ; tell window to redraw itself
1421
        mov     [edi + WDATA.fl_redraw], 1
1422
 
1423
        ; wait a bit for window to redraw itself
1424
        mov     ecx, 100
1425
 
1426
  .next_idle_cycle:
1427
        mov     byte[DONT_DRAW_MOUSE], 1
1428
        call    checkidle
1429
        cmp     [edi + WDATA.fl_redraw], 0
1430
        jz      .reset_vars
1431
        loop    .next_idle_cycle
1432
 
1433
  .reset_vars:
1434
        mov     byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
1435
        mov     byte[MOUSE_BACKGROUND], 0 ; no mouse under
1436
        mov     byte[MOUSE_DOWN], 0 ; react to mouse up/down
1437
 
1438
  .exit:
1439
        popad
1440
        ret
1441
 
1442
;==============================================================================
1443
;///// private functions //////////////////////////////////////////////////////
1444
;==============================================================================
1445
 
1446
align 4
1447
;------------------------------------------------------------------------------
1448
window._.get_titlebar_height: ;////////////////////////////////////////////////
1449
;------------------------------------------------------------------------------
1450
;> edi = pointer to WDATA
1451
;------------------------------------------------------------------------------
1452
        mov     al, [edi + WDATA.fl_wstyle]
1453
        and     al, 0x0f
1454
        cmp     al, 0x03
1455
        jne     @f
1456
        mov     eax, [_skinh]
1457
        ret
1458
    @@: mov     eax, 21
1459
        ret
1460
 
1461
align 4
1462
;------------------------------------------------------------------------------
1463
window._.get_rolledup_height: ;////////////////////////////////////////////////
1464
;------------------------------------------------------------------------------
1465
;> edi = pointer to WDATA
1466
;------------------------------------------------------------------------------
1467
        mov     al, [edi + WDATA.fl_wstyle]
1468
        and     al, 0x0f
1469
        cmp     al, 0x03
1470
        jb      @f
1471
        mov     eax, [_skinh]
1472
        add     eax, 3
1473
        ret
1474
    @@: or      al, al
1475
        jnz     @f
1476
        mov     eax, 21
1477
        ret
1478
    @@: mov     eax, 21 + 2
1479
        ret
1480
 
1481
align 4
1482
;------------------------------------------------------------------------------
1483
window._.set_screen: ;/////////////////////////////////////////////////////////
1484
;------------------------------------------------------------------------------
1485
;? Reserve window area in screen buffer
1486
;------------------------------------------------------------------------------
1487
;> eax = left
1488
;> ebx = top
1489
;> ecx = right
1490
;> edx = bottom
1491
;> esi = process number
1492
;------------------------------------------------------------------------------
1493
virtual at esp
1494
  ff_x     dd ?
1495
  ff_y     dd ?
1496
  ff_width dd ?
1497
  ff_xsz   dd ?
1498
  ff_ysz   dd ?
1499
  ff_scale dd ?
1500
end virtual
1501
 
1502
        pushad
1503
 
1504
        cmp     esi, 1
1505
        jz      .check_for_shaped_window
1506
        mov     edi, esi
1507
        shl     edi, 5
1508
        cmp     [window_data + edi + WDATA.box.width], 0
1509
        jnz     .check_for_shaped_window
1510
        cmp     [window_data + edi + WDATA.box.height], 0
1511
        jz      .exit
1512
 
1513
  .check_for_shaped_window:
1514
        mov     edi, esi
1515
        shl     edi, 8
1516
        add     edi, SLOT_BASE
1517
        cmp     [edi + APPDATA.wnd_shape], 0
1518
        jne     .shaped_window
1519
 
1520
        ; get x&y size
1521
        sub     ecx, eax
1522
        sub     edx, ebx
1523
        inc     ecx
1524
        inc     edx
1525
 
1526
        ; get WinMap start
1368 mikedld 1527
        push    esi
1362 mikedld 1528
        mov     edi, [Screen_Max_X]
1529
        inc     edi
1368 mikedld 1530
        mov     esi, edi
1362 mikedld 1531
        imul    edi, ebx
1532
        add     edi, eax
1533
        add     edi, [_WinMapAddress]
1368 mikedld 1534
        pop     eax
1535
        mov     ah, al
1536
        push    ax
1537
        shl     eax, 16
1538
        pop     ax
1362 mikedld 1539
 
1540
  .next_line:
1541
        push    ecx
1368 mikedld 1542
        shr     ecx, 2
1543
        rep     stosd
1544
        mov     ecx, [esp]
1545
        and     ecx, 3
1362 mikedld 1546
        rep     stosb
1547
        pop     ecx
1368 mikedld 1548
        add     edi, esi
1362 mikedld 1549
        sub     edi, ecx
1550
        dec     edx
1551
        jnz     .next_line
1552
 
1553
        jmp     .exit
1554
 
1555
  .shaped_window:
1556
        ;  for (y=0; y <= x_size; y++)
1557
        ;      for (x=0; x <= x_size; x++)
1558
        ;          if (shape[coord(x,y,scale)]==1)
1559
        ;             set_pixel(x, y, process_number);
1560
 
1561
        sub     ecx, eax
1562
        sub     edx, ebx
1563
        inc     ecx
1564
        inc     edx
1565
 
1566
        push    [edi + APPDATA.wnd_shape_scale]  ; push scale first -> for loop
1567
 
1568
        ; get WinMap start  -> ebp
1569
        push    eax
1570
        mov     eax, [Screen_Max_X] ; screen_sx
1571
        inc     eax
1572
        imul    eax, ebx
1573
        add     eax, [esp]
1574
        add     eax, [_WinMapAddress]
1575
        mov     ebp, eax
1576
 
1577
        mov     edi, [edi + APPDATA.wnd_shape]
1578
        pop     eax
1579
 
1580
        ; eax = x_start
1581
        ; ebx = y_start
1582
        ; ecx = x_size
1583
        ; edx = y_size
1584
        ; esi = process_number
1585
        ; edi = &shape
1586
        ;       [scale]
1587
        push    edx ecx ; for loop - x,y size
1588
 
1589
        mov     ecx, esi
1590
        shl     ecx, 5
1591
        mov     edx, [window_data + ecx + WDATA.box.top]
1592
        push    [window_data + ecx + WDATA.box.width]           ; for loop - width
1593
        mov     ecx, [window_data + ecx + WDATA.box.left]
1594
        sub     ebx, edx
1595
        sub     eax, ecx
1596
        push    ebx eax ; for loop - x,y
1597
 
1598
        add     [ff_xsz], eax
1599
        add     [ff_ysz], ebx
1600
 
1601
        mov     ebx, [ff_y]
1602
 
1603
  .ff_new_y:
1604
        mov     edx, [ff_x]
1605
 
1606
  .ff_new_x:
1607
        ; -- body --
1608
        mov     ecx, [ff_scale]
1609
        mov     eax, [ff_width]
1610
        inc     eax
1611
        shr     eax, cl
1612
        push    ebx edx
1613
        shr     ebx, cl
1614
        shr     edx, cl
1615
        imul    eax, ebx
1616
        add     eax, edx
1617
        pop     edx ebx
1618
        add     eax, edi
1619
        call    .read_byte
1620
        test    al,al
1621
        jz      @f
1622
        mov     eax, esi
1623
        mov     [ebp], al
1624
        ; -- end body --
1625
    @@: inc     ebp
1626
        inc     edx
1627
        cmp     edx, [ff_xsz]
1628
        jb      .ff_new_x
1629
 
1630
        sub     ebp, [ff_xsz]
1631
        add     ebp, [ff_x]
1632
        add     ebp, [Screen_Max_X]  ; screen.x
1633
        inc     ebp
1634
        inc     ebx
1635
        cmp     ebx, [ff_ysz]
1636
        jb      .ff_new_y
1637
 
1638
        add     esp, 24
1639
 
1640
  .exit:
1641
        popad
1642
        ret
1643
 
1644
  .read_byte:
1645
        ; eax - address
1646
        ; esi - slot
1647
        push    eax ecx edx esi
1648
        xchg    eax, esi
1649
        lea     ecx, [esp + 12]
1650
        mov     edx, 1
1651
        call    read_process_memory
1652
        pop     esi edx ecx eax
1653
        ret
1654
 
1655
align 4
1656
;------------------------------------------------------------------------------
1657
window._.window_activate: ;////////////////////////////////////////////////////
1658
;------------------------------------------------------------------------------
1659
;? Activate window
1660
;------------------------------------------------------------------------------
1661
;> esi = pointer to WIN_POS+ window data
1662
;------------------------------------------------------------------------------
1663
        push    eax ebx
1664
 
1665
        ; if type of current active window is 3 or 4, it must be redrawn
1368 mikedld 1666
        mov     ebx, [TASK_COUNT]
1667
        movzx   ebx, word[WIN_POS + ebx * 2]
1668
        shl     ebx, 5
1362 mikedld 1669
        add     eax, window_data
1368 mikedld 1670
        mov     al, [window_data + ebx + WDATA.fl_wstyle]
1671
        and     al, 0x0f
1672
        cmp     al, 0x03
1362 mikedld 1673
        je      .set_window_redraw_flag
1368 mikedld 1674
        cmp     al, 0x04
1675
        jne     .move_others_down
1362 mikedld 1676
 
1677
  .set_window_redraw_flag:
1368 mikedld 1678
        mov     [window_data + ebx + WDATA.fl_redraw], 1
1362 mikedld 1679
 
1680
  .move_others_down:
1681
        ; ax <- process no
1368 mikedld 1682
        movzx   ebx, word[esi]
1362 mikedld 1683
        ; ax <- position in window stack
1368 mikedld 1684
        movzx   ebx, word[WIN_STACK + ebx * 2]
1362 mikedld 1685
 
1686
        ; drop others
1368 mikedld 1687
        xor     eax, eax
1362 mikedld 1688
 
1689
  .next_stack_window:
1368 mikedld 1690
        cmp     eax, [TASK_COUNT]
1362 mikedld 1691
        jae     .move_self_up
1368 mikedld 1692
        inc     eax
1693
        cmp     [WIN_STACK + eax * 2], bx
1362 mikedld 1694
        jbe     .next_stack_window
1368 mikedld 1695
        dec     word[WIN_STACK + eax * 2]
1362 mikedld 1696
        jmp     .next_stack_window
1697
 
1698
  .move_self_up:
1368 mikedld 1699
        movzx   ebx, word[esi]
1362 mikedld 1700
        ; number of processes
1368 mikedld 1701
        mov     ax, [TASK_COUNT]
1362 mikedld 1702
        ; this is the last (and the upper)
1368 mikedld 1703
        mov     [WIN_STACK + ebx * 2], ax
1362 mikedld 1704
 
1705
        ; update on screen - window stack
1368 mikedld 1706
        xor     eax, eax
1362 mikedld 1707
 
1708
  .next_window_pos:
1368 mikedld 1709
        cmp     eax, [TASK_COUNT]
1362 mikedld 1710
        jae     .reset_vars
1368 mikedld 1711
        inc     eax
1712
        movzx   ebx, word[WIN_STACK + eax * 2]
1713
        mov     [WIN_POS + ebx * 2], ax
1362 mikedld 1714
        jmp     .next_window_pos
1715
 
1716
  .reset_vars:
1717
        mov     byte[KEY_COUNT], 0
1718
        mov     byte[BTN_COUNT], 0
1719
        mov     word[MOUSE_SCROLL_H], 0
1720
        mov     word[MOUSE_SCROLL_V], 0
1721
 
1722
        pop     ebx eax
1723
        ret
1724
 
1725
align 4
1726
;------------------------------------------------------------------------------
1727
window._.check_window_draw: ;//////////////////////////////////////////////////
1728
;------------------------------------------------------------------------------
1729
;? Check if window is necessary to draw
1730
;------------------------------------------------------------------------------
1731
;> edi = pointer to WDATA
1732
;------------------------------------------------------------------------------
1733
        mov     cl, [edi + WDATA.fl_wstyle]
1734
        and     cl, 0x0f
1735
        cmp     cl, 0x03
1736
        je      .exit.redraw      ; window type 3
1737
        cmp     cl, 0x04
1738
        je      .exit.redraw      ; window type 4
1739
 
1740
        push    eax ebx edx esi
1741
 
1742
        mov     eax, edi
1743
        sub     eax, window_data
1744
        shr     eax, 5
1745
 
1746
        ; esi = process number
1747
 
1748
        movzx   eax, word[WIN_STACK + eax * 2]  ; get value of the curr process
1749
        lea     esi, [WIN_POS + eax * 2]        ; get address of this process at 0xC400
1750
 
1751
  .next_window:
1752
        add     esi, 2
1753
 
1754
        mov     eax, [TASK_COUNT]
1755
        lea     eax, word[WIN_POS + eax * 2] ; number of the upper window
1756
 
1757
        cmp     esi, eax
1758
        ja      .exit.no_redraw
1759
 
1760
        movzx   edx, word[esi]
1761
        shl     edx, 5
1762
        cmp     [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
1763
        je      .next_window
1764
 
1765
        mov     eax, [edi + WDATA.box.top]
1766
        mov     ebx, [edi + WDATA.box.height]
1767
        add     ebx, eax
1768
 
1769
        mov     ecx, [window_data + edx + WDATA.box.top]
1770
        cmp     ecx, ebx
1771
        jge     .next_window
1772
        add     ecx, [window_data + edx + WDATA.box.height]
1773
        cmp     eax, ecx
1774
        jge     .next_window
1775
 
1776
        mov     eax, [edi + WDATA.box.left]
1777
        mov     ebx, [edi + WDATA.box.width]
1778
        add     ebx, eax
1779
 
1780
        mov     ecx, [window_data + edx + WDATA.box.left]
1781
        cmp     ecx, ebx
1782
        jge     .next_window
1783
        add     ecx, [window_data + edx + WDATA.box.width]
1784
        cmp     eax, ecx
1785
        jge     .next_window
1786
 
1787
        pop     esi edx ebx eax
1788
 
1789
  .exit.redraw:
1790
        xor     ecx, ecx
1791
        inc     ecx
1792
        ret
1793
 
1794
  .exit.no_redraw:
1795
        pop     esi edx ebx eax
1796
        xor     ecx, ecx
1797
        ret
1798
 
1799
align 4
1800
;------------------------------------------------------------------------------
1801
window._.draw_window_frames: ;/////////////////////////////////////////////////
1802
;------------------------------------------------------------------------------
1803
;? Draw negative window frames
1804
;------------------------------------------------------------------------------
1805
;> edi = pointer to WDATA
1806
;------------------------------------------------------------------------------
1807
        push    eax
1808
        cli
1809
 
1810
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1811
        jnz     .exit
1812
        mov     eax, [new_window_pos.left]
1813
        cmp     eax, [edi + WDATA.box.left]
1814
        jnz     .draw
1815
        mov     eax, [new_window_pos.width]
1816
        cmp     eax, [edi + WDATA.box.width]
1817
        jnz     .draw
1818
        mov     eax, [new_window_pos.top]
1819
        cmp     eax, [edi + WDATA.box.top]
1820
        jnz     .draw
1821
        mov     eax, [new_window_pos.height]
1822
        cmp     eax, [edi + WDATA.box.height]
1823
        jnz     .draw
1824
        xor     [edi + WDATA.fl_wdrawn], 2
1825
 
1826
  .draw:
1827
        push    ebx esi
1828
        mov     eax, [new_window_pos.left - 2]
1829
        mov     ax, word[new_window_pos.left]
1830
        add     ax, word[new_window_pos.width]
1831
        mov     ebx, [new_window_pos.top - 2]
1832
        mov     bx, word[new_window_pos.top]
1833
        add     bx, word[new_window_pos.height]
1834
        mov     esi, 0x01000000
1835
        call    draw_rectangle.forced
1836
        pop     esi ebx
1837
 
1838
  .exit:
1839
        sti
1840
        pop     eax
1841
        ret
1842
 
1843
  .forced:
1844
        push    eax
1845
        cli
1846
        jmp     .draw