Subversion Repositories Kolibri OS

Rev

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

  1. ;******************************************************************************
  2. ;   MAIN MENU by lisovin@26.ru
  3. ;   Some parts of code rewritten by Ivan Poddubny <ivan-yar@bk.ru>
  4. ;
  5. ;   Compile with FASM for Menuet
  6. ;******************************************************************************
  7.   include "lang.inc"
  8.   include "..\..\..\macros.inc"
  9.  
  10.   BTN_HEIGHT  = 22
  11.   TXT_Y       = (BTN_HEIGHT)/2-5
  12.  
  13.   use32
  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
  22. ;******************************************************************************
  23. ;include "DEBUG.INC"             ; debug macros
  24. START:                 ; start of execution
  25.  
  26.      mov  eax, 48         ; load system colors
  27.      mov  ebx, 3
  28.      mov  ecx, sc
  29.      mov  edx, sizeof.system_colors
  30.      mcall
  31.  
  32.      mov  eax, 70         ; load MENU.DAT
  33.      mov  ebx, fileinfo
  34.      mcall
  35.      test eax, eax         ; error ?
  36.      jz  @f
  37.      cmp  eax,6
  38.      jnz  close
  39.   @@:
  40.      test ebx, ebx         ; length = 0 ?
  41.      jz   close
  42.      mov  ecx, ebx
  43.      mov  edi, mem_end
  44.   newsearch:
  45.      mov  al, '#'
  46.      cld
  47.      repne scasb
  48.      test ecx, ecx         ; if not found
  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
  57.      add  ebx, menu_data     ; pointer to process table
  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
  92.      mcall
  93.      sub  ax, 20
  94.      mov  [menu_data + y_end],      ax
  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:
  102.      mov  eax, [buffer]      ; identifier
  103.      shl  eax, 4
  104.      add  eax, menu_data
  105.      mov  edi, eax
  106.  
  107.      mov  eax, 40         ; set event mask
  108.      mov  ebx, 100111b         ; mouse + button + key + redraw
  109.      mcall
  110.  
  111.      call draw_window
  112.  
  113. still:
  114.     mov  eax, 23         ; wait here for event
  115.     mov  ebx, 5
  116.     mcall
  117.  
  118.     test [close_now], 1      ; is close flag set?
  119.     jnz  close
  120.  
  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
  129.  
  130.     cmp  edi, menu_data
  131.     je     still             ; if main process-ignored
  132.  
  133.   movzx  ebx, [edi + parent]     ; parent id
  134.     shl  ebx, 4
  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 :)
  138.     jne  close
  139.  
  140.     jmp  still
  141.  
  142.  
  143.   red:                 ; redraw
  144.     call draw_window
  145.     jmp  still
  146.  
  147.  
  148.   key:
  149. ;   mov  eax, 2
  150.     mcall
  151.  
  152.     mov  al,  [edi + rows]     ; number of buttons
  153.  
  154.     cmp  ah,  178         ; KEY_UP
  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:
  166.     cmp  ah, 177         ; KEY_DOWN
  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:
  178.     cmp  ah, 13          ; ENTER
  179.     jne  .noenter
  180.     mov  ah, [edi + cur_sel]
  181.     jmp  button1
  182.  
  183.   .noenter:
  184.     cmp  ah, 27          ; ESC
  185.     jne  still
  186.     jmp  close
  187.  
  188. ;           include "DEBUG.INC"
  189.  
  190.   button:             ; BUTTON HANDLER
  191.     mov  eax, 17         ; get id
  192.     mcall
  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]
  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 <ah> times; <ah> = 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
  225.     test ecx, ecx         ; if '/' not found
  226.     je     searchexit
  227.  
  228.     cmp  [edi], byte '@'     ; check for submenu
  229.     je     runthread
  230.  
  231.     dec  edi
  232.     push edi             ; pointer to start of filename
  233.     call searchstartstring   ; search for next string
  234.     sub  edi, 2          ; to last byte of string
  235.  
  236.     mov  ecx, edi
  237.     pop  esi
  238.     sub  ecx, esi
  239.     inc  ecx             ; length of filename
  240.     mov  edi, fileinfo_start.name
  241.     rep  movsb             ; copy string
  242.     mov  byte [edi], 0         ; store terminator
  243.     mov  eax, 70         ; start program
  244.     mov  ebx, fileinfo_start
  245.     mcall
  246. ;    mcall 5,100
  247.     or     [close_now], 1      ; set close flag
  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
  261.     call get_number          ; get number of this process
  262.     pop  eax
  263.  
  264.     test ebx, ebx          ; returned zero - main menu or not number
  265.     jz     searchexit
  266.  
  267.     mov  al, bl
  268.  
  269.     mov  ebx, [processes]
  270.     dec  bl
  271.     cmp  al, bl
  272.     ja     searchexit          ; such process doesnt exist
  273.     cmp  al, [esi + child]
  274.     je     searchexit          ; such process already exists
  275.  
  276.     mov  [esi + child], al    ; this is my child
  277.     mov  cx, [esi + x_start]
  278.     add  cx, 141          ; new x_start in cx
  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
  285.     sub  bl,  ah          ; number of btn from bottom
  286.   movzx  eax, al
  287.     mov  [buffer], eax          ; thread id in buffer
  288.   movzx  ebx, bl
  289.     push edx
  290.     mov  eax, BTN_HEIGHT
  291.     mul  ebx
  292.     sub  cx,  ax          ; new y_end for new thread
  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
  305.     mov  [thread_stack], 0xE000
  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]
  313.     mcall
  314.  
  315.     jmp  searchexit
  316.  
  317.  
  318.  mouse:               ; MOUSE EVENT HANDLER
  319.     mov  eax, 37
  320.     mov  ebx, 2
  321.     mcall
  322.     test eax, eax          ; check buttons state
  323.     jnz  click
  324.     mov  eax, 37
  325.     mov  ebx, 1
  326.     mcall
  327.     ror  eax, 16          ; eax = [ Y | X ] relative to window
  328.     cmp  ax,  140          ; pointer in window?
  329.     ja     noinwindow
  330. ;  in window 
  331.  
  332.     shr  eax, 16          ; eax = [ 0 | Y ]
  333.     xor  edx, edx
  334.     mov  ebx, BTN_HEIGHT
  335.     div  ebx
  336.     inc  eax              ; number of "button" in eax
  337.   movzx  ebx, [edi + rows]    ; total strings in ebx
  338.     cmp  eax, ebx
  339.     ja     noinwindow
  340.     cmp  [edi + cur_sel], al
  341.     je     noredrawbut
  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)
  363.     je     close
  364.     jmp  still
  365.  
  366.  
  367.   close:
  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
  379.  
  380.   backconvert:            ; convert from pointer to process id
  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'
  401.     jb     .finish
  402.     cmp  al, '9'
  403.     ja     .finish
  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.  
  421.     mov  eax, 12           ; function 12:tell os about windowdraw
  422.     mov  ebx, 1            ; 1, start of draw
  423.     mcall
  424.  
  425.   movzx  ebx, [edi + rows]
  426.    imul  eax, ebx, BTN_HEIGHT       ; eax = height of window
  427.   movzx  ecx, [edi + y_end]
  428.     sub  ecx, eax           ; ecx = Y_START
  429.     shl  ecx, 16
  430.     add  ecx, eax           ; ecx = [ Y_START | Y_SIZE ]
  431.     dec  ecx
  432.   movzx  ebx, [edi + x_start]
  433.     shl  ebx, 16
  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
  438.     mcall
  439.  
  440.     call draw_all_buttons
  441.  
  442.     mov  eax,12
  443.     mov  ebx,2
  444.     mcall
  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]
  455.     jb     .new_button
  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
  482.     mov  esi, [sc.work]
  483.     cmp  esi, 0xdfdfdf
  484.     jb   nocorrect
  485.     sub  esi, 0x1b1b1b
  486.   nocorrect:
  487.     inc  dl
  488.     cmp  [edi + cur_sel], dl
  489.     jne  .nohighlight
  490.     add  esi, 0x1a1a1a
  491.   .nohighlight:
  492.     or     edx, 0x20000000
  493.                                 ; dunkaist[
  494.     add  edx, 0xd1ff00          ; This makes first menu buttons differ from system close button with 0x000001 id
  495.                                 ; dunkaist]
  496.     mcall
  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
  508.     je     .linefound
  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.  
  518.     mov  ecx, [sc.work_text]
  519.     mov  eax, 4
  520.     mov  esi, 21
  521.     mcall
  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.  
  539. thread_stack   dd   0xE000
  540. processes      dd   0
  541.  
  542. fileinfo:
  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
  548.  .name:
  549.      db   '/sys/MENU.DAT',0   ; ASCIIZ dir & filename
  550.  
  551. fileinfo_start:
  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
  557.  .name:
  558.    times 50 db ' '
  559.  
  560. I_END:
  561.  
  562. close_now      dd ?   ; close all processes immediately
  563. end_pointer    dd ?
  564. buffer           dd ?
  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
  574.   rows           db ?   ; +4    numer of strings
  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:
  585.