Subversion Repositories Kolibri OS

Rev

Rev 1329 | Rev 1368 | 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: 1362 $
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:
249
;> eax = 0
250
;> ebx = shape data address
251
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
252
;; Set window shape scale:
253
;> eax = 1
254
;> ebx = scale power (resulting scale is 2^ebx)
255
;------------------------------------------------------------------------------
256
        mov     edi, [current_slot]
257
 
258
        test    eax, eax
259
        jne     .shape_scale
260
        mov     [edi + APPDATA.wnd_shape], ebx
261
 
262
  .shape_scale:
263
        dec     eax
264
        jnz     .exit
265
        mov     [edi + APPDATA.wnd_shape_scale], ebx
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]
330
        ja      .skip_window
331
        mov     ebx, [edi + WDATA.box.top]
332
        cmp     ebx, [esp + RECT.bottom]
333
        ja      .skip_window
334
        mov     ecx, [edi + WDATA.box.width]
335
        add     ecx, eax
336
        cmp     ecx, [esp + RECT.left]
337
        jb      .skip_window
338
        mov     edx, [edi + WDATA.box.height]
339
        add     edx, ebx
340
        cmp     edx, [esp + RECT.top]
341
        jb      .skip_window
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
457
        jbe     .check_left
458
        mov     ecx, esi
459
        mov     [edi + WDATA.box.width], esi
460
 
461
  .check_left:
462
        or      eax, eax
463
        jg      @f
464
        xor     eax, eax
465
        jmp     .fix_left
466
    @@: add     eax, ecx
467
        cmp     eax, esi
468
        jle     .check_height
469
        mov     eax, esi
470
        sub     eax, ecx
471
 
472
  .fix_left:
473
        mov     [edi + WDATA.box.left], eax
474
 
475
  .check_height:
476
        mov     esi, [Screen_Max_Y]
477
        cmp     edx, esi
478
        jbe     .check_top
479
        mov     edx, esi
480
        mov     [edi + WDATA.box.height], esi
481
 
482
  .check_top:
483
        or      ebx, ebx
484
        jg      @f
485
        xor     ebx, ebx
486
        jmp     .fix_top
487
    @@: add     ebx, edx
488
        cmp     ebx, esi
489
        jle     .exit
490
        mov     ebx, esi
491
        sub     ebx, edx
492
 
493
  .fix_top:
494
        mov     [edi + WDATA.box.top], ebx
495
 
496
  .exit:
497
        pop     esi edx ecx ebx eax
498
        ret
499
 
500
align 4
501
;------------------------------------------------------------------------------
502
sys_window_mouse: ;////////////////////////////////////////////////////////////
503
;------------------------------------------------------------------------------
504
;? 
505
;------------------------------------------------------------------------------
506
        push    eax
507
 
508
        mov     eax, [timer_ticks]
509
        cmp     [new_window_starting], eax
510
        jb      .exit
511
 
512
        mov     byte[MOUSE_BACKGROUND], 0
513
        mov     byte[DONT_DRAW_MOUSE], 0
514
 
515
        mov     [new_window_starting], eax
516
 
517
  .exit:
518
        pop     eax
519
        ret
520
 
521
align 4
522
;------------------------------------------------------------------------------
523
draw_rectangle: ;//////////////////////////////////////////////////////////////
524
;------------------------------------------------------------------------------
525
;> eax = pack[16(left), 16(right)]
526
;> ebx = pack[16(top), 16(bottom)]
527
;> esi = color
528
;------------------------------------------------------------------------------
529
        push    eax ebx ecx edi
530
 
531
        xor     edi, edi
532
 
533
  .flags_set:
534
        push    ebx
535
 
536
        ; set line color
537
        mov     ecx, esi
538
 
539
        ; draw top border
540
        rol     ebx, 16
541
        push    ebx
542
        rol     ebx, 16
543
        pop     bx
544
        call    [draw_line]
545
 
546
        ; draw bottom border
547
        mov     ebx, [esp - 2]
548
        pop     bx
549
        call    [draw_line]
550
 
551
        pop     ebx
552
        add     ebx, 1 * 65536 - 1
553
 
554
        ; draw left border
555
        rol     eax, 16
556
        push    eax
557
        rol     eax, 16
558
        pop     ax
559
        call    [draw_line]
560
 
561
        ; draw right border
562
        mov     eax, [esp - 2]
563
        pop     ax
564
        call    [draw_line]
565
 
566
        pop     edi ecx ebx eax
567
        ret
568
 
569
  .forced:
570
        push    eax ebx ecx edi
571
        xor     edi, edi
572
        inc     edi
573
        jmp     .flags_set
574
 
575
align 4
576
;------------------------------------------------------------------------------
577
drawwindow_I_caption: ;////////////////////////////////////////////////////////
578
;------------------------------------------------------------------------------
579
;? 
580
;------------------------------------------------------------------------------
581
        push    [edx + WDATA.cl_titlebar]
582
        mov     esi, edx
583
 
584
        mov     edx, [esi + WDATA.box.top]
585
        mov     eax, edx
586
        lea     ebx, [edx + 21]
587
        inc     edx
588
        add     eax, [esi + WDATA.box.height]
589
 
590
        cmp     ebx, eax
591
        jbe     @f
592
        mov     ebx, eax
593
    @@: push    ebx
594
 
595
        xor     edi, edi
596
 
597
  .next_line:
598
        mov     ebx, edx
599
        shl     ebx, 16
600
        add     ebx, edx
601
        mov     eax, [esi + WDATA.box.left]
602
        inc     eax
603
        shl     eax, 16
604
        add     eax, [esi + WDATA.box.left]
605
        add     eax, [esi + WDATA.box.width]
606
        dec     eax
607
        mov     ecx, [esi + WDATA.cl_titlebar]
608
        test    ecx, 0x80000000
609
        jz      @f
610
        sub     ecx, 0x00040404
611
        mov     [esi + WDATA.cl_titlebar], ecx
612
    @@: and     ecx, 0x00ffffff
613
        call    [draw_line]
614
        inc     edx
615
        cmp     edx, [esp]
616
        jb      .next_line
617
 
618
        add     esp, 4
619
        pop     [esi + WDATA.cl_titlebar]
620
        ret
621
 
622
align 4
623
;------------------------------------------------------------------------------
624
drawwindow_I: ;////////////////////////////////////////////////////////////////
625
;------------------------------------------------------------------------------
626
;? 
627
;------------------------------------------------------------------------------
628
        pushad
629
 
630
        ; window border
631
 
632
        mov     eax, [edx + WDATA.box.left - 2]
633
        mov     ax, word[edx + WDATA.box.left]
634
        add     ax, word[edx + WDATA.box.width]
635
        mov     ebx, [edx + WDATA.box.top - 2]
636
        mov     bx, word[edx + WDATA.box.top]
637
        add     bx, word[edx + WDATA.box.height]
638
 
639
        mov     esi, [edx + WDATA.cl_frames]
640
        call    draw_rectangle
641
 
642
        ; window caption
643
 
644
        call    drawwindow_I_caption
645
 
646
        ; window client area
647
 
648
        ; do we need to draw it?
649
        mov     edi, [esi + WDATA.cl_workarea]
650
        test    edi, 0x40000000
651
        jnz     .exit
652
 
653
        ; does client area have a positive size on screen?
654
        mov     edx, [esi + WDATA.box.top]
655
        add     edx, 21 + 5
656
        mov     ebx, [esi + WDATA.box.top]
657
        add     ebx, [esi + WDATA.box.height]
658
        cmp     edx, ebx
659
        jg      .exit
660
 
661
        ; okay, let's draw it
662
        mov     eax, 1
663
        mov     ebx, 21
664
        mov     ecx, [esi + WDATA.box.width]
665
        mov     edx, [esi + WDATA.box.height]
666
        call    [drawbar]
667
 
668
  .exit:
669
        popad
670
        ret
671
 
672
align 4
673
;------------------------------------------------------------------------------
674
drawwindow_III_caption: ;/////////////////////////////////////////////////////
675
;------------------------------------------------------------------------------
676
;? 
677
;------------------------------------------------------------------------------
678
        mov     ecx, [edx + WDATA.cl_titlebar]
679
        push    ecx
680
        mov     esi, edx
681
        mov     edx, [esi + WDATA.box.top]
682
        add     edx, 4
683
        mov     ebx, [esi + WDATA.box.top]
684
        add     ebx, 20
685
        mov     eax, [esi + WDATA.box.top]
686
        add     eax, [esi + WDATA.box.height]
687
 
688
        cmp     ebx, eax
689
        jb      @f
690
        mov     ebx, eax
691
    @@: push    ebx
692
 
693
        xor     edi, edi
694
 
695
  .next_line:
696
        mov     ebx, edx
697
        shl     ebx, 16
698
        add     ebx, edx
699
        mov     eax, [esi + WDATA.box.left]
700
        shl     eax, 16
701
        add     eax, [esi + WDATA.box.left]
702
        add     eax, [esi + WDATA.box.width]
703
        add     eax, 4 * 65536 - 4
704
        mov     ecx, [esi + WDATA.cl_titlebar]
705
        test    ecx, 0x40000000
706
        jz      @f
707
        add     ecx, 0x00040404
708
    @@: test    ecx, 0x80000000
709
        jz      @f
710
        sub     ecx, 0x00040404
711
    @@: mov     [esi + WDATA.cl_titlebar], ecx
712
        and     ecx, 0x00ffffff
713
        call    [draw_line]
714
        inc     edx
715
        cmp     edx, [esp]
716
        jb      .next_line
717
 
718
        add     esp, 4
719
        pop     [esi + WDATA.cl_titlebar]
720
        ret
721
 
722
align 4
723
;------------------------------------------------------------------------------
724
drawwindow_III: ;//////////////////////////////////////////////////////////////
725
;------------------------------------------------------------------------------
726
;? 
727
;------------------------------------------------------------------------------
728
        pushad
729
 
730
        ; window border
731
 
732
        mov     eax, [edx + WDATA.box.left - 2]
733
        mov     ax, word[edx + WDATA.box.left]
734
        add     ax, word[edx + WDATA.box.width]
735
        mov     ebx, [edx + WDATA.box.top - 2]
736
        mov     bx, word[edx + WDATA.box.top]
737
        add     bx, word[edx + WDATA.box.height]
738
 
739
        mov     esi, [edx + WDATA.cl_frames]
740
        shr     esi, 1
741
        and     esi, 0x007f7f7f
742
        call    draw_rectangle
743
 
744
        push    esi
745
        mov     ecx, 3
746
        mov     esi, [edx + WDATA.cl_frames]
747
 
748
  .next_frame:
749
        add     eax, 1 * 65536 - 1
750
        add     ebx, 1 * 65536 - 1
751
        call    draw_rectangle
752
        dec     ecx
753
        jnz     .next_frame
754
 
755
        pop     esi
756
        add     eax, 1 * 65536 - 1
757
        add     ebx, 1 * 65536 - 1
758
        call    draw_rectangle
759
 
760
        ; window caption
761
 
762
        call    drawwindow_III_caption
763
 
764
        ; window client area
765
 
766
        ; do we need to draw it?
767
        mov     edi, [esi + WDATA.cl_workarea]
768
        test    edi, 0x40000000
769
        jnz     .exit
770
 
771
        ; does client area have a positive size on screen?
772
        mov     edx, [esi + WDATA.box.top]
773
        add     edx, 21 + 5
774
        mov     ebx, [esi + WDATA.box.top]
775
        add     ebx, [esi + WDATA.box.height]
776
        cmp     edx, ebx
777
        jg      .exit
778
 
779
        ; okay, let's draw it
780
        mov     eax, 5
781
        mov     ebx, 20
782
        mov     ecx, [esi + WDATA.box.width]
783
        mov     edx, [esi + WDATA.box.height]
784
        sub     ecx, 4
785
        sub     edx, 4
786
        call    [drawbar]
787
 
788
  .exit:
789
        popad
790
        ret
791
 
792
align 4
793
;------------------------------------------------------------------------------
794
waredraw: ;////////////////////////////////////////////////////////////////////
795
;------------------------------------------------------------------------------
796
;? Activate window, redrawing if necessary
797
;------------------------------------------------------------------------------
798
        ; is it overlapped by another window now?
799
        push    ecx
800
        call    window._.check_window_draw
801
        test    ecx, ecx
802
        pop     ecx
803
        jz      .do_not_draw
804
 
805
        ; yes it is, activate and update screen buffer
806
        mov     byte[MOUSE_DOWN], 1
807
        call    window._.window_activate
808
 
809
        pushad
810
        mov     edi, [TASK_COUNT]
811
        movzx   esi, word[WIN_POS + edi * 2]
812
        shl     esi, 5
813
        add     esi, window_data
814
 
815
        mov     eax, [esi + WDATA.box.left]
816
        mov     ebx, [esi + WDATA.box.top]
817
        mov     ecx, [esi + WDATA.box.width]
818
        mov     edx, [esi + WDATA.box.height]
819
 
820
        add     ecx, eax
821
        add     edx, ebx
822
 
823
        mov     edi, [TASK_COUNT]
824
        movzx   esi, word[WIN_POS + edi * 2]
825
        call    window._.set_screen
826
        popad
827
 
828
        ; tell application to redraw itself
829
        mov     [edi + WDATA.fl_redraw], 1
830
        mov     byte[MOUSE_DOWN], 0
831
        ret
832
 
833
  .do_not_draw:
834
        ; no it's not, just activate the window
835
        call    window._.window_activate
836
        mov     byte[MOUSE_DOWN], 0
837
        mov     byte[MOUSE_BACKGROUND], 0
838
        mov     byte[DONT_DRAW_MOUSE], 0
839
        ret
840
 
841
align 4
842
;------------------------------------------------------------------------------
843
minimize_window: ;/////////////////////////////////////////////////////////////
844
;------------------------------------------------------------------------------
845
;> eax = window number on screen
846
;------------------------------------------------------------------------------
847
;# corrupts [dl*]
848
;------------------------------------------------------------------------------
849
        push    edi
850
        pushfd
851
        cli
852
 
853
        ; is it already minimized?
854
        movzx   edi, word[WIN_POS + eax * 2]
855
        shl     edi, 5
856
        add     edi, window_data
857
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
858
        jnz     .exit
859
 
860
        push    eax ebx ecx edx esi
861
 
862
        ; no it's not, let's do that
863
        or      [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
864
        mov     eax, [edi + WDATA.box.left]
865
        mov     [draw_limits.left], eax
866
        mov     ecx, eax
867
        add     ecx, [edi + WDATA.box.width]
868
        mov     [draw_limits.right], ecx
869
        mov     ebx, [edi + WDATA.box.top]
870
        mov     [draw_limits.top], ebx
871
        mov     edx, ebx
872
        add     edx, [edi + WDATA.box.height]
873
        mov     [draw_limits.bottom], edx
874
        call    calculatescreen
875
        xor     esi, esi
876
        xor     eax, eax
877
        call    redrawscreen
878
 
879
        pop     esi edx ecx ebx eax
880
 
881
  .exit:
882
        popfd
883
        pop     edi
884
        ret
885
 
886
align 4
887
;------------------------------------------------------------------------------
888
restore_minimized_window: ;////////////////////////////////////////////////////
889
;------------------------------------------------------------------------------
890
;> eax = window number on screen
891
;------------------------------------------------------------------------------
892
;# corrupts [dl*]
893
;------------------------------------------------------------------------------
894
        pushad
895
        pushfd
896
        cli
897
 
898
        ; is it already restored?
899
        movzx   esi, word[WIN_POS + eax * 2]
900
        mov     edi, esi
901
        shl     edi, 5
902
        add     edi, window_data
903
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
904
        jz      .exit
905
 
906
        ; no it's not, let's do that
907
        mov     [edi + WDATA.fl_redraw], 1
908
        and     [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
909
        mov     ebp, window._.set_screen
910
        cmp     eax, [TASK_COUNT]
911
        jz      @f
912
        mov     ebp, calculatescreen
913
    @@: mov     eax, [edi + WDATA.box.left]
914
        mov     ebx, [edi + WDATA.box.top]
915
        mov     ecx, [edi + WDATA.box.width]
916
        mov     edx, [edi + WDATA.box.height]
917
        add     ecx, eax
918
        add     edx, ebx
919
        call    ebp
920
 
921
        mov     byte[MOUSE_BACKGROUND], 0
922
 
923
  .exit:
924
        popfd
925
        popad
926
        ret
927
 
928
align 4
929
;------------------------------------------------------------------------------
930
checkwindows: ;////////////////////////////////////////////////////////////////
931
;------------------------------------------------------------------------------
932
;? Check for user-initiated window operations
933
;------------------------------------------------------------------------------
934
        pushad
935
 
936
        ; do we have window minimize/restore request?
937
        cmp     [window_minimize], 0
938
        je      .check_for_mouse_buttons_state
939
 
940
        ; okay, minimize or restore top-most window and exit
941
        mov     eax, [TASK_COUNT]
942
        mov     bl, 0
943
        xchg    [window_minimize], bl
944
        dec     bl
945
        jnz     @f
946
        call    minimize_window
947
        jmp     .check_for_mouse_buttons_state
948
    @@: call    restore_minimized_window
949
 
950
  .check_for_mouse_buttons_state:
951
        ; do we have any mouse buttons pressed?
952
        cmp     byte[BTN_DOWN], 0
953
        jne     .mouse_buttons_pressed
954
 
955
        mov     [bPressedMouseXY_W], 0
956
        jmp     .exit
957
 
958
  .mouse_buttons_pressed:
959
        ; yes we do, iterate and ...
960
        mov     esi, [TASK_COUNT]
961
        inc     esi
962
 
963
        cmp     [bPressedMouseXY_W], 1
964
        ja      .next_window
965
        inc     [bPressedMouseXY_W]
966
        jnc     .next_window
967
        push    dword[MOUSE_X]
968
        pop     dword[mx]
969
 
970
  .next_window:
971
        cmp     esi, 2
972
        jb      .exit
973
 
974
        dec     esi
975
 
976
        ; is that window not minimized?
977
        movzx   edi, word[WIN_POS + esi * 2]
978
        shl     edi, 5
979
        add     edi, window_data
980
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
981
        jnz     .next_window
982
 
983
        movzx   eax, [mx]
984
        movzx   ebx, [my]
985
 
986
        ; is the cursor inside screen bounds of that window?
987
        mov     ecx, [edi + WDATA.box.left]
988
        mov     edx, [edi + WDATA.box.top]
989
        cmp     eax, ecx
990
        jl      .next_window
991
        cmp     ebx, edx
992
        jl      .next_window
993
        add     ecx, [edi + WDATA.box.width]
994
        add     edx, [edi + WDATA.box.height]
995
        cmp     eax, ecx
996
        jge     .next_window
997
        cmp     ebx, edx
998
        jge     .next_window
999
 
1000
        ; is that a top-most (which means active) window?
1001
        cmp     esi, [TASK_COUNT]
1002
        je      .check_for_moving_or_resizing
1003
 
1004
        ; no it's not, did we just press mouse button down above it or was it
1005
        ; already pressed before?
1006
        cmp     [bPressedMouseXY_W], 1
1007
        ja      .exit
1008
 
1009
        ; okay, we just pressed the button, activate this window and exit
1010
        lea     esi, [WIN_POS + esi * 2]
1011
        call    waredraw
1012
        jmp     .exit
1013
 
1014
  .check_for_moving_or_resizing:
1015
        ; is that window movable?
1016
        test    byte[edi + WDATA.cl_titlebar + 3], 0x01
1017
        jnz     .exit
1018
 
1019
        ; yes it is, is it rolled up?
1020
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1021
        jnz     .check_for_cursor_on_caption
1022
 
1023
        ; no it's not, can it be resized then?
1024
        mov     [do_resize_from_corner], 0
1025
        mov     dl, [edi + WDATA.fl_wstyle]
1026
        and     dl, 0x0f
1027
        cmp     dl, 0x00
1028
        je      .check_for_cursor_on_caption
1029
        cmp     dl, 0x01
1030
        je      .check_for_cursor_on_caption
1031
        cmp     dl, 0x04
1032
        je      .check_for_cursor_on_caption
1033
 
1034
        ; are we going to resize it?
1035
        mov     edx, [edi + WDATA.box.top]
1036
        add     edx, [edi + WDATA.box.height]
1037
        sub     edx, 6
1038
        cmp     ebx, edx
1039
        jl      .check_for_cursor_on_caption
1040
 
1041
        ; yes we do, remember that
1042
        mov     [do_resize_from_corner], 1
1043
        jmp     .set_move_resize_flag
1044
 
1045
  .check_for_cursor_on_caption:
1046
        ; is the cursor inside window titlebar?
1047
        push    eax
1048
        call    window._.get_titlebar_height
1049
        add     eax, [edi + WDATA.box.top]
1050
        cmp     ebx, eax
1051
        pop     eax
1052
        jge     .exit
1053
 
1054
        ; calculate duration between two clicks
1055
        mov     ecx, [timer_ticks]
1056
        mov     edx, ecx
1057
        sub     edx, [latest_window_touch]
1058
        mov     [latest_window_touch], ecx
1059
        mov     [latest_window_touch_delta], edx
1060
 
1061
  .set_move_resize_flag:
1062
        mov     cl, [BTN_DOWN]
1063
        mov     [do_resize], cl
1064
 
1065
        mov     ecx, [edi + WDATA.box.left]
1066
        mov     edx, [edi + WDATA.box.top]
1067
 
1068
        push    ecx edx
1069
        mov     [draw_limits.left], ecx
1070
        mov     [draw_limits.top], edx
1071
        add     ecx, [edi + WDATA.box.width]
1072
        add     edx, [edi + WDATA.box.height]
1073
        mov     [draw_limits.right], ecx
1074
        mov     [draw_limits.bottom], edx
1075
        pop     edx ecx
1076
 
1077
        ; calculate window-relative cursor coordinates
1078
        sub     eax, ecx
1079
        sub     ebx, edx
1080
 
1081
        push    dword[MOUSE_X]
1082
        pop     dword[WIN_TEMP_XY]
1083
 
1084
        ; save old window coordinates
1085
        push    eax
1086
        mov     eax, [edi + WDATA.box.left]
1087
        mov     [old_window_pos.left], eax
1088
        mov     [new_window_pos.left], eax
1089
        mov     eax, [edi + WDATA.box.top]
1090
        mov     [old_window_pos.top], eax
1091
        mov     [new_window_pos.top], eax
1092
        mov     eax, [edi + WDATA.box.width]
1093
        mov     [old_window_pos.width], eax
1094
        mov     [new_window_pos.width], eax
1095
        mov     eax, [edi + WDATA.box.height]
1096
        mov     [old_window_pos.height], eax
1097
        mov     [new_window_pos.height], eax
1098
        pop     eax
1099
 
1100
        ; draw negative moving/sizing frame
1101
        call    window._.draw_window_frames
1102
 
1103
        mov     [reposition], 0
1104
        mov     byte[MOUSE_DOWN], 1
1105
 
1106
  .next_mouse_state_check:
1107
        ; process OS events
1108
        mov     byte[DONT_DRAW_MOUSE], 1
1109
        call    checkidle
1110
        call    checkVga_N13
1111
        mov     byte[MOUSE_BACKGROUND], 0
1112
        call    [draw_pointer]
1113
        pushad
1114
        call    stack_handler
1115
        popad
1116
 
1117
        ; did cursor position change?
1118
        mov     esi, [WIN_TEMP_XY]
1119
        cmp     esi, [MOUSE_X]
1120
        je      .check_for_new_mouse_buttons_state
1121
 
1122
        ; yes it did, calculate window-relative cursor coordinates
1123
        movzx   ecx, word[MOUSE_X]
1124
        movzx   edx, word[MOUSE_Y]
1125
        sub     ecx, eax
1126
        sub     edx, ebx
1127
 
1128
        push    eax ebx
1129
 
1130
        ; we're going to draw new frame, erasing the old one
1131
        call    window._.draw_window_frames
1132
 
1133
        ; are we moving it right now?
1134
        cmp     [do_resize_from_corner], 0
1135
        jne     .resize_window
1136
 
1137
        ; yes we do, check if it's inside the screen area
1138
        mov     eax, [Screen_Max_X]
1139
        mov     ebx, [Screen_Max_Y]
1140
 
1141
        mov     [new_window_pos.left], 0
1142
        or      ecx, ecx
1143
        jle     .check_for_new_vert_cursor_pos
1144
        mov     [reposition], 1
1145
        sub     eax, [new_window_pos.width]
1146
        mov     [new_window_pos.left], eax
1147
        cmp     ecx, eax
1148
        jge     .check_for_new_vert_cursor_pos
1149
        mov     [new_window_pos.left], ecx
1150
 
1151
  .check_for_new_vert_cursor_pos:
1152
        mov     [new_window_pos.top], 0
1153
        or      edx, edx
1154
        jle     .draw_new_window_frame
1155
        mov     [reposition], 1
1156
        sub     ebx, [new_window_pos.height]
1157
        mov     [new_window_pos.top], ebx
1158
        cmp     edx, ebx
1159
        jge     .draw_new_window_frame
1160
        mov     [new_window_pos.top], edx
1161
        jmp     .draw_new_window_frame
1162
 
1163
  .resize_window:
1164
        push    eax ebx edx
1165
 
1166
        mov     edx, edi
1167
        sub     edx, window_data
1168
        lea     edx, [SLOT_BASE + edx * 8]
1169
 
1170
        movzx   eax, word[MOUSE_X]
1171
        cmp     eax, [edi + WDATA.box.left]
1172
        jb      .fix_new_vert_size
1173
        sub     eax, [edi + WDATA.box.left]
1174
        cmp     eax, 32
1175
        jge     @f
1176
        mov     eax, 32
1177
    @@: mov     [new_window_pos.width], eax
1178
 
1179
  .fix_new_vert_size:
1180
        call    window._.get_rolledup_height
1181
        mov     ebx, eax
1182
        movzx   eax, word[MOUSE_Y]
1183
        cmp     eax, [edi + WDATA.box.top]
1184
        jb      .set_reposition_flag
1185
        sub     eax, [edi + WDATA.box.top]
1186
        cmp     eax, ebx
1187
        jge     @f
1188
        mov     eax, ebx
1189
    @@: mov     [new_window_pos.height], eax
1190
 
1191
  .set_reposition_flag:
1192
        mov     [reposition], 1
1193
 
1194
        pop     edx ebx eax
1195
 
1196
  .draw_new_window_frame:
1197
        pop     ebx eax
1198
 
1199
        ; draw new window moving/sizing frame
1200
        call    window._.draw_window_frames
1201
 
1202
        mov     esi, [MOUSE_X]
1203
        mov     [WIN_TEMP_XY], esi
1204
 
1205
  .check_for_new_mouse_buttons_state:
1206
        ; did user release mouse button(s)?
1207
        cmp     byte[BTN_DOWN], 0
1208
        jne     .next_mouse_state_check
1209
 
1210
        ; yes he did, moving/sizing is over
1211
        mov     byte[DONT_DRAW_MOUSE], 1
1212
        mov     cl, 0
1213
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1214
        jnz     .check_other_actions
1215
 
1216
        mov     cl, [reposition]
1217
 
1218
        ; draw negative frame once again to hide it
1219
        call    window._.draw_window_frames
1220
 
1221
        ; save new window bounds
1222
        mov     eax, [new_window_pos.left]
1223
        mov     [edi + WDATA.box.left], eax
1224
        mov     eax, [new_window_pos.top]
1225
        mov     [edi + WDATA.box.top], eax
1226
        mov     eax, [new_window_pos.width]
1227
        mov     [edi + WDATA.box.width], eax
1228
        mov     eax, [new_window_pos.height]
1229
        mov     [edi + WDATA.box.height], eax
1230
        call    set_window_clientbox
1231
 
1232
        cmp     cl, 1
1233
        jne     .check_other_actions
1234
        push    esi edi ecx
1235
        mov     esi, edi
1236
        mov     ecx, 2
1237
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED
1238
        jnz     @f
1239
        add     ecx, 2
1240
    @@: sub     edi, window_data
1241
        shr     edi, 5
1242
        shl     edi, 8
1243
        add     edi, SLOT_BASE + APPDATA.saved_box
1244
        cld
1245
        rep     movsd
1246
        pop     ecx edi esi
1247
 
1248
  .check_other_actions:
1249
        mov     [reposition], cl
1250
 
1251
        pushad
1252
 
1253
        mov     dl, [edi + WDATA.fl_wstyle]
1254
        and     dl, 0x0f
1255
        cmp     dl, 0x00
1256
        je      .check_if_window_fits_screen
1257
        cmp     dl, 0x01
1258
        je      .check_if_window_fits_screen
1259
 
1260
        cmp     cl, 1
1261
        je      .no_window_sizing
1262
        mov     edx, edi
1263
        sub     edx, window_data
1264
        shr     edx, 5
1265
        shl     edx, 8
1266
        add     edx, SLOT_BASE
1267
 
1268
        ; did we right-click on titlebar?
1269
        cmp     [do_resize], 2
1270
        jne     .check_maximization_request
1271
 
1272
        ; yes we did, toggle normal/rolled up window state
1273
        xor     [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1274
        mov     [reposition], 1
1275
 
1276
        ; calculate and set appropriate window height
1277
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1278
        jz      @f
1279
        call    window._.get_rolledup_height
1280
        jmp     .set_new_window_height
1281
    @@: mov     eax, [edx + APPDATA.saved_box.height]
1282
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1283
        jz      .set_new_window_height
1284
        mov     eax, [screen_workarea.bottom]
1285
        sub     eax, [screen_workarea.top]
1286
 
1287
  .set_new_window_height:
1288
        mov     [edi + WDATA.box.height], eax
1289
        add     eax, [edi + WDATA.box.top]
1290
        cmp     eax, [Screen_Max_Y]
1291
        jbe     @f
1292
        mov     eax, [Screen_Max_Y]
1293
        sub     eax, [edi + WDATA.box.height]
1294
        mov     [edi + WDATA.box.top], eax
1295
    @@: call    check_window_position
1296
        call    set_window_clientbox
1297
 
1298
  .check_maximization_request:
1299
        ; can window change its height?
1300
        push    edx
1301
        mov     dl, [edi + WDATA.fl_wstyle]
1302
        and     dl, 0x0f
1303
        cmp     dl, 0x04
1304
        pop     edx
1305
        je      .check_if_window_fits_screen
1306
 
1307
        ; was it really a maximize/restore request?
1308
        cmp     [do_resize], 1
1309
        jne     .check_if_window_fits_screen
1310
        cmp     [do_resize_from_corner], 0
1311
        jne     .check_if_window_fits_screen
1312
        cmp     [latest_window_touch_delta], 50
1313
        jg      .check_if_window_fits_screen
1314
 
1315
        ; yes is was, toggle normal/maximized window state
1316
        xor     [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1317
        mov     [reposition], 1
1318
 
1319
        ; calculate and set appropriate window bounds
1320
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1321
        jz      .restore_normal_window_size
1322
        mov     eax, [screen_workarea.left]
1323
        mov     [edi + WDATA.box.left], eax
1324
        sub     eax, [screen_workarea.right]
1325
        neg     eax
1326
        mov     [edi + WDATA.box.width], eax
1327
        mov     eax, [screen_workarea.top]
1328
        mov     [edi + WDATA.box.top], eax
1329
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1330
        jnz     .calculate_window_client_area
1331
        sub     eax, [screen_workarea.bottom]
1332
        neg     eax
1333
        mov     [edi + WDATA.box.height], eax
1334
        jmp     .calculate_window_client_area
1335
 
1336
  .restore_normal_window_size:
1337
        push    [edi + WDATA.box.height]
1338
        push    edi
1339
        lea     esi, [edx + APPDATA.saved_box]
1340
        mov     ecx, 4
1341
        cld
1342
        rep     movsd
1343
        pop     edi
1344
        pop     eax
1345
        test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
1346
        jz      .calculate_window_client_area
1347
        mov     [edi + WDATA.box.height], eax
1348
 
1349
  .calculate_window_client_area:
1350
        call    set_window_clientbox
1351
 
1352
  .check_if_window_fits_screen:
1353
        ; does window fit into screen area?
1354
        mov     eax, [edi + WDATA.box.top]
1355
        add     eax, [edi + WDATA.box.height]
1356
        cmp     eax, [Screen_Max_Y]
1357
        jbe     .no_window_sizing
1358
        mov     eax, [edi + WDATA.box.left]
1359
        add     eax, [edi + WDATA.box.width]
1360
        cmp     eax, [Screen_Max_X]
1361
        jbe     .no_window_sizing
1362
 
1363
        ; no it doesn't, fix that
1364
        mov     eax, [Screen_Max_X]
1365
        sub     eax, [edi + WDATA.box.width]
1366
        mov     [edi + WDATA.box.left], eax
1367
        mov     eax, [Screen_Max_Y]
1368
        sub     eax, [edi + WDATA.box.height]
1369
        mov     [edi + WDATA.box.top], eax
1370
        call    set_window_clientbox
1371
 
1372
  .no_window_sizing:
1373
        popad
1374
 
1375
        ; did somethins actually change its place?
1376
        cmp     [reposition], 0
1377
        je      .reset_vars
1378
 
1379
        mov     byte[DONT_DRAW_MOUSE], 1
1380
 
1381
        push    eax ebx ecx edx
1382
 
1383
        ; recalculate screen buffer at new position
1384
        mov     eax, [edi + WDATA.box.left]
1385
        mov     ebx, [edi + WDATA.box.top]
1386
        mov     ecx, [edi + WDATA.box.width]
1387
        mov     edx, [edi + WDATA.box.height]
1388
        add     ecx, eax
1389
        add     edx, ebx
1390
        call    calculatescreen
1391
 
1392
        ; recalculate screen buffer at old position
1393
        mov     eax, [old_window_pos.left]
1394
        mov     ebx, [old_window_pos.top]
1395
        mov     ecx, [old_window_pos.width]
1396
        mov     edx, [old_window_pos.height]
1397
        add     ecx, eax
1398
        add     edx, ebx
1399
        call    calculatescreen
1400
 
1401
        pop     edx ecx ebx eax
1402
 
1403
        mov     eax, edi
1404
        call    redrawscreen
1405
 
1406
        ; tell window to redraw itself
1407
        mov     [edi + WDATA.fl_redraw], 1
1408
 
1409
        ; wait a bit for window to redraw itself
1410
        mov     ecx, 100
1411
 
1412
  .next_idle_cycle:
1413
        mov     byte[DONT_DRAW_MOUSE], 1
1414
        call    checkidle
1415
        cmp     [edi + WDATA.fl_redraw], 0
1416
        jz      .reset_vars
1417
        loop    .next_idle_cycle
1418
 
1419
  .reset_vars:
1420
        mov     byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
1421
        mov     byte[MOUSE_BACKGROUND], 0 ; no mouse under
1422
        mov     byte[MOUSE_DOWN], 0 ; react to mouse up/down
1423
 
1424
  .exit:
1425
        popad
1426
        ret
1427
 
1428
;==============================================================================
1429
;///// private functions //////////////////////////////////////////////////////
1430
;==============================================================================
1431
 
1432
align 4
1433
;------------------------------------------------------------------------------
1434
window._.get_titlebar_height: ;////////////////////////////////////////////////
1435
;------------------------------------------------------------------------------
1436
;> edi = pointer to WDATA
1437
;------------------------------------------------------------------------------
1438
        mov     al, [edi + WDATA.fl_wstyle]
1439
        and     al, 0x0f
1440
        cmp     al, 0x03
1441
        jne     @f
1442
        mov     eax, [_skinh]
1443
        ret
1444
    @@: mov     eax, 21
1445
        ret
1446
 
1447
align 4
1448
;------------------------------------------------------------------------------
1449
window._.get_rolledup_height: ;////////////////////////////////////////////////
1450
;------------------------------------------------------------------------------
1451
;> edi = pointer to WDATA
1452
;------------------------------------------------------------------------------
1453
        mov     al, [edi + WDATA.fl_wstyle]
1454
        and     al, 0x0f
1455
        cmp     al, 0x03
1456
        jb      @f
1457
        mov     eax, [_skinh]
1458
        add     eax, 3
1459
        ret
1460
    @@: or      al, al
1461
        jnz     @f
1462
        mov     eax, 21
1463
        ret
1464
    @@: mov     eax, 21 + 2
1465
        ret
1466
 
1467
align 4
1468
;------------------------------------------------------------------------------
1469
window._.set_screen: ;/////////////////////////////////////////////////////////
1470
;------------------------------------------------------------------------------
1471
;? Reserve window area in screen buffer
1472
;------------------------------------------------------------------------------
1473
;> eax = left
1474
;> ebx = top
1475
;> ecx = right
1476
;> edx = bottom
1477
;> esi = process number
1478
;------------------------------------------------------------------------------
1479
virtual at esp
1480
  ff_x     dd ?
1481
  ff_y     dd ?
1482
  ff_width dd ?
1483
  ff_xsz   dd ?
1484
  ff_ysz   dd ?
1485
  ff_scale dd ?
1486
end virtual
1487
 
1488
        pushad
1489
 
1490
        cmp     esi, 1
1491
        jz      .check_for_shaped_window
1492
        mov     edi, esi
1493
        shl     edi, 5
1494
        cmp     [window_data + edi + WDATA.box.width], 0
1495
        jnz     .check_for_shaped_window
1496
        cmp     [window_data + edi + WDATA.box.height], 0
1497
        jz      .exit
1498
 
1499
  .check_for_shaped_window:
1500
        mov     edi, esi
1501
        shl     edi, 8
1502
        add     edi, SLOT_BASE
1503
        cmp     [edi + APPDATA.wnd_shape], 0
1504
        jne     .shaped_window
1505
 
1506
        ; get x&y size
1507
        sub     ecx, eax
1508
        sub     edx, ebx
1509
        inc     ecx
1510
        inc     edx
1511
 
1512
        ; get WinMap start
1513
        mov     edi, [Screen_Max_X]
1514
        inc     edi
1515
        imul    edi, ebx
1516
        add     edi, eax
1517
        add     edi, [_WinMapAddress]
1518
        mov     eax, esi
1519
 
1520
  .next_line:
1521
        push    ecx
1522
        rep     stosb
1523
        pop     ecx
1524
        add     edi, [Screen_Max_X]
1525
        inc     edi
1526
        sub     edi, ecx
1527
        dec     edx
1528
        jnz     .next_line
1529
 
1530
        jmp     .exit
1531
 
1532
  .shaped_window:
1533
        ;  for (y=0; y <= x_size; y++)
1534
        ;      for (x=0; x <= x_size; x++)
1535
        ;          if (shape[coord(x,y,scale)]==1)
1536
        ;             set_pixel(x, y, process_number);
1537
 
1538
        sub     ecx, eax
1539
        sub     edx, ebx
1540
        inc     ecx
1541
        inc     edx
1542
 
1543
        push    [edi + APPDATA.wnd_shape_scale]  ; push scale first -> for loop
1544
 
1545
        ; get WinMap start  -> ebp
1546
        push    eax
1547
        mov     eax, [Screen_Max_X] ; screen_sx
1548
        inc     eax
1549
        imul    eax, ebx
1550
        add     eax, [esp]
1551
        add     eax, [_WinMapAddress]
1552
        mov     ebp, eax
1553
 
1554
        mov     edi, [edi + APPDATA.wnd_shape]
1555
        pop     eax
1556
 
1557
        ; eax = x_start
1558
        ; ebx = y_start
1559
        ; ecx = x_size
1560
        ; edx = y_size
1561
        ; esi = process_number
1562
        ; edi = &shape
1563
        ;       [scale]
1564
        push    edx ecx ; for loop - x,y size
1565
 
1566
        mov     ecx, esi
1567
        shl     ecx, 5
1568
        mov     edx, [window_data + ecx + WDATA.box.top]
1569
        push    [window_data + ecx + WDATA.box.width]           ; for loop - width
1570
        mov     ecx, [window_data + ecx + WDATA.box.left]
1571
        sub     ebx, edx
1572
        sub     eax, ecx
1573
        push    ebx eax ; for loop - x,y
1574
 
1575
        add     [ff_xsz], eax
1576
        add     [ff_ysz], ebx
1577
 
1578
        mov     ebx, [ff_y]
1579
 
1580
  .ff_new_y:
1581
        mov     edx, [ff_x]
1582
 
1583
  .ff_new_x:
1584
        ; -- body --
1585
        mov     ecx, [ff_scale]
1586
        mov     eax, [ff_width]
1587
        inc     eax
1588
        shr     eax, cl
1589
        push    ebx edx
1590
        shr     ebx, cl
1591
        shr     edx, cl
1592
        imul    eax, ebx
1593
        add     eax, edx
1594
        pop     edx ebx
1595
        add     eax, edi
1596
        call    .read_byte
1597
        test    al,al
1598
        jz      @f
1599
        mov     eax, esi
1600
        mov     [ebp], al
1601
        ; -- end body --
1602
    @@: inc     ebp
1603
        inc     edx
1604
        cmp     edx, [ff_xsz]
1605
        jb      .ff_new_x
1606
 
1607
        sub     ebp, [ff_xsz]
1608
        add     ebp, [ff_x]
1609
        add     ebp, [Screen_Max_X]  ; screen.x
1610
        inc     ebp
1611
        inc     ebx
1612
        cmp     ebx, [ff_ysz]
1613
        jb      .ff_new_y
1614
 
1615
        add     esp, 24
1616
 
1617
  .exit:
1618
        popad
1619
        ret
1620
 
1621
  .read_byte:
1622
        ; eax - address
1623
        ; esi - slot
1624
        push    eax ecx edx esi
1625
        xchg    eax, esi
1626
        lea     ecx, [esp + 12]
1627
        mov     edx, 1
1628
        call    read_process_memory
1629
        pop     esi edx ecx eax
1630
        ret
1631
 
1632
align 4
1633
;------------------------------------------------------------------------------
1634
window._.window_activate: ;////////////////////////////////////////////////////
1635
;------------------------------------------------------------------------------
1636
;? Activate window
1637
;------------------------------------------------------------------------------
1638
;> esi = pointer to WIN_POS+ window data
1639
;------------------------------------------------------------------------------
1640
        push    eax ebx
1641
 
1642
        ; if type of current active window is 3 or 4, it must be redrawn
1643
        mov     eax, [TASK_COUNT]
1644
        movzx   eax, word[WIN_POS + eax * 2]
1645
        shl     eax, 5
1646
        add     eax, window_data
1647
        mov     bl, [eax + WDATA.fl_wstyle]
1648
        and     bl, 0x0f
1649
        cmp     bl, 0x03
1650
        je      .set_window_redraw_flag
1651
        cmp     bl, 0x04
1652
        je      .set_window_redraw_flag
1653
        jmp     .move_others_down
1654
 
1655
  .set_window_redraw_flag:
1656
        mov     [eax + WDATA.fl_redraw], 1
1657
 
1658
  .move_others_down:
1659
        ; ax <- process no
1660
        movzx   eax, word[esi]
1661
        ; ax <- position in window stack
1662
        movzx   eax, word[WIN_STACK + eax * 2]
1663
 
1664
        ; drop others
1665
        xor     ebx, ebx
1666
 
1667
  .next_stack_window:
1668
        cmp     ebx, [TASK_COUNT]
1669
        jae     .move_self_up
1670
        inc     ebx
1671
        cmp     [WIN_STACK + ebx * 2], ax
1672
        jbe     .next_stack_window
1673
        dec     word[WIN_STACK + ebx * 2]
1674
        jmp     .next_stack_window
1675
 
1676
  .move_self_up:
1677
        movzx   eax, word[esi]
1678
        ; number of processes
1679
        mov     bx, [TASK_COUNT]
1680
        ; this is the last (and the upper)
1681
        mov     [WIN_STACK + eax * 2], bx
1682
 
1683
        ; update on screen - window stack
1684
        xor     ebx, ebx
1685
 
1686
  .next_window_pos:
1687
        cmp     ebx, [TASK_COUNT]
1688
        jae     .reset_vars
1689
        inc     ebx
1690
        movzx   eax, word[WIN_STACK + ebx * 2]
1691
        mov     [WIN_POS + eax * 2], bx
1692
        jmp     .next_window_pos
1693
 
1694
  .reset_vars:
1695
        mov     byte[KEY_COUNT], 0
1696
        mov     byte[BTN_COUNT], 0
1697
        mov     word[MOUSE_SCROLL_H], 0
1698
        mov     word[MOUSE_SCROLL_V], 0
1699
 
1700
        pop     ebx eax
1701
        ret
1702
 
1703
align 4
1704
;------------------------------------------------------------------------------
1705
window._.check_window_draw: ;//////////////////////////////////////////////////
1706
;------------------------------------------------------------------------------
1707
;? Check if window is necessary to draw
1708
;------------------------------------------------------------------------------
1709
;> edi = pointer to WDATA
1710
;------------------------------------------------------------------------------
1711
        mov     cl, [edi + WDATA.fl_wstyle]
1712
        and     cl, 0x0f
1713
        cmp     cl, 0x03
1714
        je      .exit.redraw      ; window type 3
1715
        cmp     cl, 0x04
1716
        je      .exit.redraw      ; window type 4
1717
 
1718
        push    eax ebx edx esi
1719
 
1720
        mov     eax, edi
1721
        sub     eax, window_data
1722
        shr     eax, 5
1723
 
1724
        ; esi = process number
1725
 
1726
        movzx   eax, word[WIN_STACK + eax * 2]  ; get value of the curr process
1727
        lea     esi, [WIN_POS + eax * 2]        ; get address of this process at 0xC400
1728
 
1729
  .next_window:
1730
        add     esi, 2
1731
 
1732
        mov     eax, [TASK_COUNT]
1733
        lea     eax, word[WIN_POS + eax * 2] ; number of the upper window
1734
 
1735
        cmp     esi, eax
1736
        ja      .exit.no_redraw
1737
 
1738
        movzx   edx, word[esi]
1739
        shl     edx, 5
1740
        cmp     [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
1741
        je      .next_window
1742
 
1743
        mov     eax, [edi + WDATA.box.top]
1744
        mov     ebx, [edi + WDATA.box.height]
1745
        add     ebx, eax
1746
 
1747
        mov     ecx, [window_data + edx + WDATA.box.top]
1748
        cmp     ecx, ebx
1749
        jge     .next_window
1750
        add     ecx, [window_data + edx + WDATA.box.height]
1751
        cmp     eax, ecx
1752
        jge     .next_window
1753
 
1754
        mov     eax, [edi + WDATA.box.left]
1755
        mov     ebx, [edi + WDATA.box.width]
1756
        add     ebx, eax
1757
 
1758
        mov     ecx, [window_data + edx + WDATA.box.left]
1759
        cmp     ecx, ebx
1760
        jge     .next_window
1761
        add     ecx, [window_data + edx + WDATA.box.width]
1762
        cmp     eax, ecx
1763
        jge     .next_window
1764
 
1765
        pop     esi edx ebx eax
1766
 
1767
  .exit.redraw:
1768
        xor     ecx, ecx
1769
        inc     ecx
1770
        ret
1771
 
1772
  .exit.no_redraw:
1773
        pop     esi edx ebx eax
1774
        xor     ecx, ecx
1775
        ret
1776
 
1777
align 4
1778
;------------------------------------------------------------------------------
1779
window._.draw_window_frames: ;/////////////////////////////////////////////////
1780
;------------------------------------------------------------------------------
1781
;? Draw negative window frames
1782
;------------------------------------------------------------------------------
1783
;> edi = pointer to WDATA
1784
;------------------------------------------------------------------------------
1785
        push    eax
1786
        cli
1787
 
1788
        test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
1789
        jnz     .exit
1790
        mov     eax, [new_window_pos.left]
1791
        cmp     eax, [edi + WDATA.box.left]
1792
        jnz     .draw
1793
        mov     eax, [new_window_pos.width]
1794
        cmp     eax, [edi + WDATA.box.width]
1795
        jnz     .draw
1796
        mov     eax, [new_window_pos.top]
1797
        cmp     eax, [edi + WDATA.box.top]
1798
        jnz     .draw
1799
        mov     eax, [new_window_pos.height]
1800
        cmp     eax, [edi + WDATA.box.height]
1801
        jnz     .draw
1802
        xor     [edi + WDATA.fl_wdrawn], 2
1803
 
1804
  .draw:
1805
        push    ebx esi
1806
        mov     eax, [new_window_pos.left - 2]
1807
        mov     ax, word[new_window_pos.left]
1808
        add     ax, word[new_window_pos.width]
1809
        mov     ebx, [new_window_pos.top - 2]
1810
        mov     bx, word[new_window_pos.top]
1811
        add     bx, word[new_window_pos.height]
1812
        mov     esi, 0x01000000
1813
        call    draw_rectangle.forced
1814
        pop     esi ebx
1815
 
1816
  .exit:
1817
        sti
1818
        pop     eax
1819
        ret
1820
 
1821
  .forced:
1822
        push    eax
1823
        cli
1824
        jmp     .draw