Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
31 halyavin 1
;******************************************************************************
2
;   MAIN MENU by lisovin@26.ru
3
;   Some parts of code rewritten by Ivan Poddubny 
4
;
5
;   Compile with FASM for Menuet
6
;******************************************************************************
7
  include "lang.inc"
485 heavyiron 8
  include "..\..\..\macros.inc"
31 halyavin 9
 
10
  BTN_HEIGHT  = 22
11
  TXT_Y       = (BTN_HEIGHT)/2-5
12
 
13
  use32
97 mario79 14
  org	  0x0
15
  db	 'MENUET01'	    ; 8 byte id
16
  dd	 0x01		  ; header version
17
  dd	 START		   ; start of code
18
  dd	 I_END		   ; size of image
19
  dd	 0x20000	 ; memory for app
20
  dd	 0x20000-1	     ; esp
21
  dd	 0x0 , 0x0	   ; I_Param , I_Icon
31 halyavin 22
;******************************************************************************
23
;include "DEBUG.INC"             ; debug macros
97 mario79 24
START:		       ; start of execution
31 halyavin 25
 
97 mario79 26
     mov  eax, 48	  ; load system colors
31 halyavin 27
     mov  ebx, 3
28
     mov  ecx, sc
29
     mov  edx, sizeof.system_colors
485 heavyiron 30
     mcall
31 halyavin 31
 
97 mario79 32
     mov  eax, 70	  ; load MENU.DAT
31 halyavin 33
     mov  ebx, fileinfo
485 heavyiron 34
     mcall
97 mario79 35
     test eax, eax	   ; error ?
36
     jz  @f
37
     cmp  eax,6
31 halyavin 38
     jnz  close
97 mario79 39
  @@:
40
     test ebx, ebx	   ; length = 0 ?
31 halyavin 41
     jz   close
42
     mov  ecx, ebx
43
     mov  edi, mem_end
44
  newsearch:
45
     mov  al, '#'
46
     cld
47
     repne scasb
97 mario79 48
     test ecx, ecx	   ; if not found
31 halyavin 49
     jz   close
50
     call get_number
51
     test ebx, ebx
52
     jnz  .number
53
     cmp  al, '#'
54
     je   search_end
55
   .number:
56
     shl  ebx, 4
97 mario79 57
     add  ebx, menu_data     ; pointer to process table
31 halyavin 58
     mov  [ebx], edi
59
     inc  [processes]
60
     jmp  newsearch
61
  search_end:
62
     mov  [end_pointer], edi
63
     mov  ebx, [processes]
64
     dec  ebx
65
     shl  ebx, 4
66
     add  ebx, menu_data
67
  newprocess:
68
     xor  edx, edx
69
     mov  ecx, edi
70
     sub  ecx, [ebx]
71
     mov  al, 10
72
  newsearch1:
73
     std
74
     repne scasb
75
     test ecx, ecx
76
     je   endprocess
77
     cmp  [edi], byte 13
78
     jne  newsearch1
79
     inc  edx
80
     jmp  newsearch1
81
  endprocess:
82
     mov  esi, ebx
83
     add  esi, 4
84
     dec  edx
85
     mov  [esi], dl
86
     cmp  ebx, menu_data
87
     jbe  search_end1
88
     sub  ebx, 16
89
     jmp  newprocess
90
  search_end1:
91
     mov  eax, 14
485 heavyiron 92
     mcall
31 halyavin 93
     sub  ax, 20
97 mario79 94
     mov  [menu_data + y_end],	    ax
31 halyavin 95
     mov  [menu_data + x_start],  5
96
     mov  al, [menu_data + rows]
97
     mov  [menu_data + cur_sel],  al	 ; clear selection
98
     mov  [menu_data + prev_sel], al
99
 
100
     mov  [buffer], 0
101
  thread:
97 mario79 102
     mov  eax, [buffer]      ; identifier
31 halyavin 103
     shl  eax, 4
104
     add  eax, menu_data
105
     mov  edi, eax
106
 
97 mario79 107
     mov  eax, 40	  ; set event mask
108
     mov  ebx, 100111b	       ; mouse + button + key + redraw
485 heavyiron 109
     mcall
31 halyavin 110
 
111
     call draw_window
112
 
113
still:
97 mario79 114
    mov  eax, 23	 ; wait here for event
31 halyavin 115
    mov  ebx, 5
485 heavyiron 116
    mcall
31 halyavin 117
 
97 mario79 118
    test [close_now], 1      ; is close flag set?
31 halyavin 119
    jnz  close
120
 
97 mario79 121
    cmp  eax, 1 	 ; redraw request ?
122
    je	   red
123
    cmp  eax, 2 	 ; key pressed ?
124
    je	   key
125
    cmp  eax, 3 	 ; button in buffer ?
126
    je	   button
127
    cmp  eax, 6 	 ; mouse event ?
128
    je	   mouse
31 halyavin 129
 
130
    cmp  edi, menu_data
97 mario79 131
    je	   still	     ; if main process-ignored
31 halyavin 132
 
133
  movzx  ebx, [edi + parent]	 ; parent id
134
    shl  ebx, 4
97 mario79 135
    add  ebx, menu_data      ; ebx = base of parent info
136
    call backconvert	     ; get my id in al
137
    cmp  al, [ebx + child]    ; if I'm not child of my parent, I shall die :)
31 halyavin 138
    jne  close
139
 
140
    jmp  still
141
 
142
 
97 mario79 143
  red:		       ; redraw
31 halyavin 144
    call draw_window
145
    jmp  still
146
 
147
 
148
  key:
149
;   mov  eax, 2
485 heavyiron 150
    mcall
31 halyavin 151
 
97 mario79 152
    mov  al,  [edi + rows]     ; number of buttons
31 halyavin 153
 
97 mario79 154
    cmp  ah,  178	  ; KEY_UP
31 halyavin 155
    jne  .noup
156
 
157
    mov  ah,  [edi+cur_sel]
158
    mov  [edi+prev_sel], ah
159
    dec  byte [edi+cur_sel]
160
    jnz  redrawbut
161
    mov  [edi+cur_sel], al
162
    jmp  redrawbut
163
 
164
 
165
  .noup:
97 mario79 166
    cmp  ah, 177	 ; KEY_DOWN
31 halyavin 167
    jne  .nodn
168
 
169
    mov  ah, [edi + cur_sel]
170
    mov  [edi + prev_sel], ah
171
    inc  [edi + cur_sel]
172
    cmp  [edi + cur_sel], al
173
    jna  redrawbut
174
    mov  [edi + cur_sel], 1
175
    jmp  redrawbut
176
 
177
  .nodn:
97 mario79 178
    cmp  ah, 13 	 ; ENTER
31 halyavin 179
    jne  .noenter
180
    mov  ah, [edi + cur_sel]
181
    jmp  button1
182
 
183
  .noenter:
97 mario79 184
    cmp  ah, 27 	 ; ESC
31 halyavin 185
    jne  still
186
    jmp  close
187
 
188
;           include "DEBUG.INC"
189
 
97 mario79 190
  button:	      ; BUTTON HANDLER
191
    mov  eax, 17	 ; get id
485 heavyiron 192
    mcall
1754 dunkaist 193
                        ; dunkaist[
194
    test eax,0xfffffe00 ; is it system close button? (close signal from @panel)
195
    setz byte[close_now]; set (or not set) close_recursive flag
196
     jz  close          ; if so, close all menus
197
                        ; dunkaist]
31 halyavin 198
  button1:
199
    mov  esi, edi
200
    push edi
201
    mov  edi, [edi + pointer]
202
 
203
; print "hello"
204
    mov  al, [esi + cur_sel]
205
    mov  [esi + prev_sel], al
206
    mov  [esi + cur_sel], ah
207
    pushad
208
    mov edi, esi
209
;    dph eax
210
    call draw_only_needed_buttons
211
    popad
212
 
213
    ; look for the next line  times;  = button_id
214
    push eax
215
  .next_string:
216
    call searchstartstring
217
    dec  ah
218
    jnz  .next_string
219
    pop  eax
220
 
221
    mov  ecx, 40
222
    mov  al, '/'
223
    cld
224
  repne  scasb
97 mario79 225
    test ecx, ecx	  ; if '/' not found
226
    je	   searchexit
31 halyavin 227
 
228
    cmp  [edi], byte '@'     ; check for submenu
97 mario79 229
    je	   runthread
31 halyavin 230
 
231
    dec  edi
97 mario79 232
    push edi		 ; pointer to start of filename
31 halyavin 233
    call searchstartstring   ; search for next string
97 mario79 234
    sub  edi, 2 	 ; to last byte of string
31 halyavin 235
 
236
    mov  ecx, edi
237
    pop  esi
238
    sub  ecx, esi
97 mario79 239
    inc  ecx		 ; length of filename
31 halyavin 240
    mov  edi, fileinfo_start.name
97 mario79 241
    rep  movsb		   ; copy string
242
    mov  byte [edi], 0	       ; store terminator
243
    mov  eax, 70	 ; start program
31 halyavin 244
    mov  ebx, fileinfo_start
485 heavyiron 245
    mcall
97 mario79 246
;    mcall 5,100
247
    or	   [close_now], 1      ; set close flag
31 halyavin 248
    pop  edi
249
    mov  [mousemask], 0
250
    jmp  close
251
 
252
  searchexit:
253
    pop  edi
254
    jmp  still
255
 
256
 
257
  runthread:
258
    inc  edi
259
 
260
    push eax
97 mario79 261
    call get_number	     ; get number of this process
31 halyavin 262
    pop  eax
263
 
97 mario79 264
    test ebx, ebx	   ; returned zero - main menu or not number
265
    jz	   searchexit
31 halyavin 266
 
267
    mov  al, bl
268
 
269
    mov  ebx, [processes]
270
    dec  bl
271
    cmp  al, bl
97 mario79 272
    ja	   searchexit	       ; such process doesnt exist
31 halyavin 273
    cmp  al, [esi + child]
97 mario79 274
    je	   searchexit	       ; such process already exists
31 halyavin 275
 
276
    mov  [esi + child], al    ; this is my child
277
    mov  cx, [esi + x_start]
97 mario79 278
    add  cx, 141	  ; new x_start in cx
31 halyavin 279
  movzx  edx, al
280
    shl  edx, 4
281
    add  edx, menu_data       ; edx points to child's base address
282
    mov  [edx + x_start], cx  ; xstart for new thread
283
    mov  cx,  [esi + y_end]   ; y_end in cx
284
    mov  bl,  [esi + rows]    ; number of buttons in bl
97 mario79 285
    sub  bl,  ah	  ; number of btn from bottom
31 halyavin 286
  movzx  eax, al
97 mario79 287
    mov  [buffer], eax		; thread id in buffer
31 halyavin 288
  movzx  ebx, bl
289
    push edx
290
    mov  eax, BTN_HEIGHT
291
    mul  ebx
97 mario79 292
    sub  cx,  ax	  ; new y_end for new thread
31 halyavin 293
    pop  edx
294
    mov  [edx + y_end], cx    ; store y_end
295
    mov  edi, esi
296
    call backconvert	      ; get number of this process (al)
297
    mov  [edx + parent], al   ; store number of parent process
298
    mov  al, [edx + rows]
299
    mov  [edx + cur_sel], al  ; clear current selected element
300
    mov  [edx + prev_sel], al ; clear previous selected element
301
    mov  [edx + child], 0
302
 
303
    cmp  [thread_stack], 0x1e000
304
    jne  thread_stack_not_full
97 mario79 305
    mov  [thread_stack], 0xE000
31 halyavin 306
 
307
thread_stack_not_full:
308
    add  [thread_stack], 0x2000 ; start new thread
309
    mov  eax, 51
310
    mov  ebx, 1
311
    mov  ecx, thread
312
    mov  edx, [thread_stack]
485 heavyiron 313
    mcall
31 halyavin 314
 
315
    jmp  searchexit
316
 
317
 
97 mario79 318
 mouse: 	      ; MOUSE EVENT HANDLER
31 halyavin 319
    mov  eax, 37
320
    mov  ebx, 2
485 heavyiron 321
    mcall
97 mario79 322
    test eax, eax	   ; check buttons state
31 halyavin 323
    jnz  click
324
    mov  eax, 37
325
    mov  ebx, 1
485 heavyiron 326
    mcall
97 mario79 327
    ror  eax, 16	  ; eax = [ Y | X ] relative to window
328
    cmp  ax,  140	   ; pointer in window?
329
    ja	   noinwindow
31 halyavin 330
;  in window 
331
 
97 mario79 332
    shr  eax, 16	  ; eax = [ 0 | Y ]
31 halyavin 333
    xor  edx, edx
334
    mov  ebx, BTN_HEIGHT
335
    div  ebx
97 mario79 336
    inc  eax		  ; number of "button" in eax
31 halyavin 337
  movzx  ebx, [edi + rows]    ; total strings in ebx
338
    cmp  eax, ebx
97 mario79 339
    ja	   noinwindow
31 halyavin 340
    cmp  [edi + cur_sel], al
97 mario79 341
    je	   noredrawbut
31 halyavin 342
    mov  bl, [edi + cur_sel]
343
 
344
   ;;;;;;
345
    cmp  [edi + child], 0
346
    jne  noredrawbut
347
   ;;;;;;
348
 
349
    mov  [edi + cur_sel], al
350
    mov  [edi + prev_sel], bl
351
  redrawbut:
352
    call draw_only_needed_buttons
353
  noredrawbut:
354
    call backconvert
355
    bts  [mousemask], eax
356
    jmp  still
357
  noinwindow:
358
    call backconvert
359
    btr  [mousemask], eax
360
    jmp  still
361
  click:
362
    cmp  [mousemask], 0  ; not in a window (i.e. menu)
97 mario79 363
    je	   close
31 halyavin 364
    jmp  still
365
 
366
 
367
  close:
728 diamond 368
        movzx   ebx, [edi+parent]       ; parent id
369
        shl     ebx, 4
370
        add     ebx, menu_data          ; ebx = base of parent info
371
        call    backconvert
372
        cmp     [ebx + child], al       ; if i am the child of my parent...
373
        jnz     @f
374
        mov     [ebx + child], -1       ; ...my parent now has no children
375
@@:
376
        or      eax, -1                 ; close this thread
377
        mov     [edi + child], al       ; my child is not mine
378
        mcall
31 halyavin 379
 
97 mario79 380
  backconvert:		  ; convert from pointer to process id
31 halyavin 381
    mov  eax, edi
382
    sub  eax, menu_data
383
    shr  eax, 4
384
    ret
385
 
386
 
387
;==================================
388
; get_number
389
;    load number from [edi] to ebx
390
;==================================
391
  get_number:
392
    push edi
393
 
394
    xor  eax, eax
395
    xor  ebx, ebx
396
 
397
   .get_next_char:
398
    mov  al, [edi]
399
    inc  edi
400
    cmp  al, '0'
97 mario79 401
    jb	   .finish
31 halyavin 402
    cmp  al, '9'
97 mario79 403
    ja	   .finish
31 halyavin 404
    sub  al, '0'
405
    imul ebx, 10
406
    add  ebx, eax
407
    jmp  .get_next_char
408
 
409
   .finish:
410
    pop  edi
411
    ret
412
 
413
 
414
;   *********************************************
415
;   *******  WINDOW DEFINITIONS AND DRAW ********
416
;   *********************************************
417
 
418
 
419
draw_window:
420
 
97 mario79 421
    mov  eax, 12	   ; function 12:tell os about windowdraw
422
    mov  ebx, 1 	   ; 1, start of draw
485 heavyiron 423
    mcall
31 halyavin 424
 
425
  movzx  ebx, [edi + rows]
97 mario79 426
   imul  eax, ebx, BTN_HEIGHT	    ; eax = height of window
31 halyavin 427
  movzx  ecx, [edi + y_end]
97 mario79 428
    sub  ecx, eax	    ; ecx = Y_START
31 halyavin 429
    shl  ecx, 16
97 mario79 430
    add  ecx, eax	    ; ecx = [ Y_START | Y_SIZE ]
31 halyavin 431
    dec  ecx
432
  movzx  ebx, [edi + x_start]
433
    shl  ebx, 16
97 mario79 434
    mov  bx,  140	    ; ebx = [ X_START | X_SIZE ]
435
    xor  eax, eax	    ; function 0 : define and draw window
436
    mov  edx, 0x01000000       ; color of work area RRGGBB,8->color gl
437
    mov  esi, edx	    ; unmovable window
485 heavyiron 438
    mcall
31 halyavin 439
 
440
    call draw_all_buttons
441
 
442
    mov  eax,12
443
    mov  ebx,2
485 heavyiron 444
    mcall
31 halyavin 445
 
446
    ret
447
 
448
 
449
 draw_all_buttons:
450
    xor  edx, edx
451
  .new_button:
452
    call draw_one_button
453
    inc  edx
454
    cmp  dl, [edi + rows]
97 mario79 455
    jb	   .new_button
31 halyavin 456
 
457
    ret
458
 
459
 
460
 draw_only_needed_buttons:
461
    xor  edx, edx
462
    mov  dl, [edi + cur_sel]
463
    dec  dl
464
    call draw_one_button
465
    mov  dl, [edi + prev_sel]
466
    dec  dl
467
    call draw_one_button
468
    ret
469
 
470
 
471
 draw_one_button:
472
 ; receives number of button in dl
473
    push edx;ad
474
 
475
    mov  eax, 8
476
    mov  ebx, 140
477
  movzx  ecx, dl
478
    imul ecx, BTN_HEIGHT
479
    shl  ecx, 16
480
    add  ecx, BTN_HEIGHT-1
481
;   edx = button identifier
195 heavyiron 482
    mov  esi, [sc.work]
318 heavyiron 483
    cmp  esi, 0xdfdfdf
484
    jb   nocorrect
485
    sub  esi, 0x1b1b1b
486
  nocorrect:
31 halyavin 487
    inc  dl
488
    cmp  [edi + cur_sel], dl
489
    jne  .nohighlight
318 heavyiron 490
    add  esi, 0x1a1a1a
31 halyavin 491
  .nohighlight:
97 mario79 492
    or	   edx, 0x20000000
1754 dunkaist 493
                                ; dunkaist[
494
    add  edx, 0xd1ff00          ; This makes first menu buttons differ from system close button with 0x000001 id
495
                                ; dunkaist]
485 heavyiron 496
    mcall
31 halyavin 497
    movzx edx, dl
498
 
499
    dec  dl
500
    imul ebx, edx, BTN_HEIGHT
501
    add  ebx, (4 shl 16) + TXT_Y
502
 
503
  movzx  ecx, dl
504
    inc  ecx
505
    mov  edx, [edi + pointer]
506
  .findline:
507
    cmp  byte [edx], 13
97 mario79 508
    je	   .linefound
31 halyavin 509
    inc  edx
510
    jmp  .findline
511
  .linefound:
512
    inc  edx
513
    cmp  byte [edx], 10
514
    jne  .findline
515
    dec  ecx
516
    jnz  .findline
517
 
195 heavyiron 518
    mov  ecx, [sc.work_text]
31 halyavin 519
    mov  eax, 4
520
    mov  esi, 21
485 heavyiron 521
    mcall
31 halyavin 522
 
523
    pop  edx;ad
524
    ret
525
 
526
 
527
 searchstartstring:
528
    mov  ecx, 40
529
    mov  al, 13
530
    cld
531
  repne  scasb
532
    cmp  byte [edi], 10
533
    jne  searchstartstring
534
    ret
535
 
536
 
537
;*** DATA AREA ****************************************************************
538
 
97 mario79 539
thread_stack   dd   0xE000
31 halyavin 540
processes      dd   0
541
 
542
fileinfo:
97 mario79 543
 .subfunction	 dd   0 	      ; 0=READ
544
 .start 	 dd   0 	      ; start byte
545
 .size_high	 dd   0 	      ; rezerved
546
 .size		 dd   0x10000-mem_end ; blocks to read
547
 .return	 dd   mem_end	      ; return data pointer
31 halyavin 548
 .name:
529 spraid 549
     db   '/sys/MENU.DAT',0   ; ASCIIZ dir & filename
31 halyavin 550
 
551
fileinfo_start:
97 mario79 552
 .subfunction	 dd   7 	 ; 7=START APPLICATION
553
 .flags 	 dd   0 	 ; flags
554
 .params	 dd   0x0	 ; nop
555
 .rezerved	 dd   0x0	 ; nop
556
 .rezerved_1	 dd   0x0	 ; nop
31 halyavin 557
 .name:
558
   times 50 db ' '
559
 
560
I_END:
561
 
562
close_now      dd ?   ; close all processes immediately
563
end_pointer    dd ?
97 mario79 564
buffer		 dd ?
31 halyavin 565
mousemask      dd ?   ; mask for mouse pointer location
566
 
567
sc system_colors
568
 
569
menu_data:
570
  rb 0x4000  ;x10000
571
 
572
virtual at 0	      ; PROCESSES TABLE (located at menu_data)
573
  pointer      dd ?   ; +0    pointer in file
97 mario79 574
  rows		 db ?	; +4    numer of strings
31 halyavin 575
  x_start      dw ?   ; +5    x start
576
  y_end        dw ?   ; +7    y end
577
  child        db ?   ; +9    id of child menu
578
  parent       db ?   ; +10   id of parent menu
579
  cur_sel      db ?   ; +11   current selection
580
  prev_sel     db ?   ; +12   previous selection
581
  rb	       16-$+1 ; [16 bytes per element]
582
end virtual
583
 
584
mem_end: