Subversion Repositories Kolibri OS

Rev

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

  1. ;
  2. ;   DESKTOP CONTEXT MENU
  3. ;   written by Ivan Poddubny
  4. ;
  5. ;   Автор - Иван Поддубный
  6. ;   e-mail: ivan-yar@bk.ru
  7. ;
  8. ;   Compile with flat assembler
  9. ;
  10. include 'lang.inc'
  11. include 'macros.inc'
  12.  
  13. meos_app_start
  14. code
  15.  
  16.   mov   eax,40       ; установим маску событий
  17.   mov   ebx,100000b  ; нас интересует только мышь
  18.   int   0x40
  19.  
  20. still:               ; главный цикл основного процесса
  21.  
  22.   mov   eax,10       ; ждём события
  23.   int   0x40
  24.  
  25.   mov   eax,37       ; какие нажаты кпопки?
  26.   mov   ebx,2
  27.   int   0x40
  28.  
  29.   cmp   eax,2        ; если не правая, возврат
  30.   jne   still
  31.  
  32. ;---поехали!---
  33.  
  34. ;  mov   eax,37       ; это для отладки - если мышь в точке (0;0), закроемся
  35. ;  xor   ebx,ebx
  36. ;  int   0x40
  37. ;  test  eax,eax      ; курсор в точке (0;0), т.е. eax = 0
  38. ;  je    exit
  39.  
  40.  
  41.   mov   eax,9        ; получим число процессов в системе
  42.   mov   ebx,procinfo
  43.   xor   ecx,ecx
  44.   int   0x40
  45.  
  46.   inc   eax          ; теперь в eax содержится число процессов + 1
  47.   mov   [processes],eax
  48.   mov   ecx,1
  49.  
  50.  new_process:
  51.   pushad
  52.   mov   eax,9        ; получим информацию о процессе; номер - в ecx
  53.   mov   ebx,procinfo
  54.   int   0x40
  55.   mov   eax,37       ; координаты курсора
  56.   xor   ebx,ebx
  57.   int   0x40
  58.   mov   ebx,eax                  ; eax = cursor_x
  59.   shr   eax,16                   ; ebx = cursor_y
  60.   and   ebx,0xffff
  61.   mov   [curx1],eax              ; curx1 = cursor_x
  62.   mov   [cury1],ebx              ; cury1 = cursor_y
  63. ; \begin{diamond}[18.09.2006]
  64. ; ignore minimized windows
  65.         test    [procinfo.wnd_state], 2
  66.         jnz     ne_goden
  67. ; \end{diamond}[18.09.2006]
  68.   mov   eax,[procinfo.x_start]   ; eax = wnd_x_start
  69.   mov   ebx,[procinfo.y_start]   ; ebx = wnd_y_start
  70.  
  71.   mov   ecx,[procinfo.x_size]
  72.   add   ecx,eax                  ; ecx = wnd_x_end
  73.   mov   edx,[procinfo.y_size]
  74.   add   edx,ebx                  ; ecx = wnd_y_end
  75.  
  76.   cmp   eax,[curx1]  ; wnd_x_start > cursor_x => курсор левее окна
  77.   jg    ne_goden
  78.   cmp   ecx,[curx1]  ; wnd_x_end   < cursor_x => курсор правее окна
  79.   jl    ne_goden
  80.   cmp   ebx,[cury1]  ; wnd_y_start > cursor_y => курсор выше окна
  81.   jg    ne_goden
  82.   cmp   edx,[cury1]  ; wnd_y_end   < cursor_y => курсор ниже окна
  83.   jl    ne_goden
  84.  
  85. goden:               ; клик был внутри какого-то окна, поэтому ничего не делаем
  86.   popad
  87.   jmp   still
  88.  
  89. ne_goden:            ; клик был снаружи рассматриваемого окна, поэтому
  90.   popad
  91.   inc   ecx
  92.   cmp   ecx,[processes]
  93.   jl    new_process  ; либо сморим следующее окно, либо запускаем меню
  94.  
  95.  
  96. @@:             ; подождём, пока пользователь не отпустил правую кнопку мыши
  97.   mov   eax,37
  98.   mov   ebx,2   ; функция 37-2:
  99.   int   0x40    ;   нажаты ли кнопки мыши?
  100.   cmp   eax,ebx ; если отпустил, (eax != 2)
  101.   jnz   @f      ;   идём в начало главного цикла
  102.  
  103.   mov   eax,5   ; иначе
  104.   mov   ebx,2   ;   подождём 2 мс
  105.   int   0x40
  106.  
  107.   jmp   @b      ;   и проверим мышь опять
  108. @@:
  109.  
  110. ; если уже было открыто меню, нужно подождать, пока оно закроется:
  111. @@:
  112.   cmp   [menu_opened],0
  113.   je    @f
  114.   mov   eax,5
  115.   mov   ebx,3  ; ждём 3 мс
  116.   int   0x40
  117.   jmp   @b
  118. @@:
  119.  
  120.   mov   eax,51           ; а теперь можно смело запускать процесс (поток) меню
  121.   mov   ebx,1            ; создаём поток (thread)
  122.   mov   ecx,start_wnd    ; точка входа потока
  123.   mov   edx,stack_wnd    ; вершина стэка для потока
  124.   int   0x40
  125.  
  126.   jmp   still
  127.  
  128.  
  129.  
  130. exit_menu:            ; если выходим из меню, надо записать в [menu_opened] 0
  131.   mov   [menu_opened],0
  132. exit:                 ; сюда мы идём, когда выходим из основного процесса
  133.   or    eax,-1        ; eax = -1
  134.   int   0x40
  135.  
  136.  
  137.  
  138.  
  139. ; здесь стартует процесс меню
  140. start_wnd:
  141.   mov   [menu_opened],1
  142.   mov   eax,40      ; установим маску желаемых событий для этого процесса
  143.   mov   ebx,100101b ; меню + кнопки + перерисовка
  144.   int   0x40
  145.  
  146. red:
  147.   call  draw_window
  148.  
  149. still2:             ; главный цикл процесса меню
  150.  
  151.   mov   eax,10      ; ждём события
  152.   int   0x40
  153.  
  154.   cmp   eax,1       ; перерисовка?
  155.   je    red
  156.   cmp   eax,3       ; кнопка?
  157.   je    button
  158.   cmp   eax,6       ; мышь?
  159.   je    mouse
  160.  
  161.   jmp   still2      ; вернёмся в начало главного цикла
  162.  
  163.  
  164. ; ОБРАБОТЧИК МЫШИ
  165. mouse:            ; когда пользователь нажмёт кнопку мыши, закроемся
  166.   mov   eax,37
  167.   mov   ebx,2     ; какие кнопки нажаты?
  168.   int   0x40
  169.   test  eax,eax   ; никакие? - тогда прекрасно! вернёмся в гланый цикл
  170.   jz    still2
  171.   jmp   exit_menu ; а если всё-таки нажаты - закроем окно
  172.  
  173.  
  174. ; НАЖАТА КНОПКА
  175. button:
  176.   mov   eax,17        ; получить идентификатор нажатой кнопки
  177.   int   0x40
  178.  
  179.   sub   ah,10         ; сравниваем с 10
  180.   jl    nofuncbtns    ; если меньше - закрываем меню
  181.  
  182.   movzx ebx,ah        ; получили номер программы в списке в ebx
  183.   mov   esi, [startapps + ebx*4]
  184.   mov   edi, start_info.path
  185.   cld
  186.  @@:
  187.   lodsb
  188.   stosb
  189.   test  al, al
  190.   jnz   @b
  191.   mcall 70, start_info
  192.  
  193. ;  mov   eax,5         ; подождём, пока программа запуститься
  194. ;  mov   ebx,1         ; а то её окно не будет отрисовано (баг в ядре???)
  195. ;  int   0x40          ; раскомментируйте эти строки, если у вас проблемы
  196.                        ; с отрисовкой
  197.  
  198. nofuncbtns:           ; закрываем меню
  199.   jmp   exit_menu
  200.  
  201.  
  202.  
  203. _BTNS_            = 8     ; количество кнопок ("пунктов меню")
  204.  
  205. if lang eq ru
  206.   font            = 0x00000000
  207.   string_length   = 20          ; длина строки
  208.   wnd_x_size      = 133         ; ширина окна
  209.   header_pos      = 36 shl 16 + 7
  210. else
  211.   font            = 0x10000000
  212.   string_length   = 12          ; длина строки
  213.   wnd_x_size      = 105         ; ширина окна
  214.   header_pos      = 23 shl 16 + 7
  215. end if
  216.  
  217. ;*******************************
  218. ;********  РИСУЕМ ОКНО  ********
  219. ;*******************************
  220.  
  221. draw_window:
  222.  
  223.   mov   eax,12           ; начинаем "рисовать"
  224.   mov   ebx,1
  225.   int   0x40
  226.  
  227.   mov   eax,[curx1]      ; текущие координаты курсора
  228.   mov   [curx],eax       ; запишем в координаты окна
  229.   mov   eax,[cury1]
  230.   mov   [cury],eax
  231.  
  232. ; теперь будем считать координаты окна, чтобы оно за край экрана не вылезло
  233.   mov   eax,14                ; получим размер экрана
  234.   int   0x40
  235.   mov   ebx,eax
  236.   shr   eax,16                ; в eax - x_screen
  237.   and   ebx,0xffff            ; в ebx - y_screen
  238.   add   eax,-wnd_x_size       ; eax = [x_screen - ширина окна]
  239.   add   ebx,-_BTNS_*15-21     ; ebx = [y_screen - высота окна]
  240.  
  241.   cmp   eax,[curx]
  242.   jg    .okx                  ; если окно слишком близко к правому краю,
  243.   add   [curx],-wnd_x_size    ; сдвинем его влево на 100
  244.  .okx:
  245.  
  246.   cmp   ebx, [cury]
  247.   jg    .oky                  ; по вертикали точно также
  248.   add   [cury], -_BTNS_*15-21
  249.  .oky:
  250.  
  251.   mov   eax, 48                   ; получить системные цвета
  252.   mov   ebx, 3
  253.   mov   ecx, sc                   ;  адрес структуры
  254.   mov   edx, sizeof.system_colors ;  и ее размер
  255.   int   0x40
  256.  
  257.   xor   eax, eax           ; функция 0 - создать окно
  258.   mov   ebx, [curx]        ;  ebx = [координата по x] shl 16 + [ширина]
  259.   shl   ebx, 16
  260.   add   ebx, wnd_x_size
  261.   mov   ecx, [cury]        ;  ecx = [координата по y] shl 16 + [высота]
  262.   shl   ecx, 16
  263.   add   ecx, _BTNS_*15+21
  264.   mov   edx, [sc.work]     ;  цвет рабочей области
  265.   mov   esi, [sc.grab]     ;  цвет заголовка
  266.   or    esi, 0x81000000
  267.   mov   edi, [sc.frame]    ;  цвет рамки
  268.   int   0x40
  269.  
  270.   mov   eax, 4             ; заголовок
  271.   mov   ebx, header_pos    ;  [x] shl 16 + [y]
  272.   mov   ecx, [sc.grab_text];  шрифт и цвет (серый)
  273.   or    ecx, 0x10000000
  274. ;  add   ecx, -0x333333
  275.   push  ecx
  276.   push  ecx
  277.   xor   edx,edx
  278. .dec_color:
  279.   sub   byte [esp+edx], 0x33
  280.   jae   @f
  281.   mov   byte [esp+edx], 0
  282. @@:
  283.   inc   edx
  284.   jnp   .dec_color
  285.   pop   ecx
  286.   mov   edx, header        ;  адрес заголовка
  287.   mov   esi, header.size   ;  длина заголовка ("M E N U")
  288.   int   0x40
  289.   pop   ecx
  290.   add   ebx, 1 shl 16      ;  сдвинем вправо на 1
  291.   int   0x40
  292.  
  293.   mov   ebx, 1*65536+wnd_x_size-2  ; начинаем делать кнопки
  294.   mov   ecx, 20*65536+15
  295.   mov   edx, 10 or 0x40000000 ; бит 30 установлен => кнопка не рисуется
  296.  
  297.   mov   edi,_BTNS_           ; количество кнопок (счётчик)
  298.  
  299.  newbtn:                     ; начало цикла
  300.   mov   eax,8                ;  создаём кнопку
  301.   int   0x40
  302.  
  303.                              ;  пишем текст на кнопке
  304.   pushad                     ;   спасаем регистры
  305.   shr   ecx, 16
  306.   and   ebx, 0xffff0000
  307.   add   ebx, ecx             ;   ebx = [x] shl 16 + [y];
  308.   add   ebx, 10*65536+4      ;   ebx += смещение относительно края кнопки;
  309.   mov   ecx, [sc.work_text]  ;   шрифт и цвет
  310.   or    ecx, font
  311.   add   edx, -10             ;   edx = номер кнопки;
  312.   imul  edx, string_length   ;   edx *= длина строки;
  313.   add   edx, text            ;   edx += text;  теперь в edx адрес строки
  314.   mov   esi, string_length   ;   в esi - длина строки
  315.   mov   eax, 4               ;   функция 4 - вывод текста
  316.   int   0x40
  317.   popad
  318.  
  319.   inc   edx                  ;  номер кнопки++;
  320.   add   ecx,15*65536         ;  увеличим смещение по y
  321.   dec   edi                  ;  уменьшим счётчик
  322.   jnz   newbtn               ; если не ноль, повторим всё ещё раз
  323.  
  324.   mov   eax,12               ; закончили "рисовать"
  325.   mov   ebx,2
  326.   int   0x40
  327.  
  328. ret                          ; возврат
  329.  
  330.  
  331.  
  332. ; ДАННЫЕ ПРОГРАММЫ
  333. DATA
  334.  
  335.   macro strtbl name, [string]
  336.   {
  337.    common
  338.      label name dword
  339.    forward
  340.      local str
  341.      dd str
  342.    forward
  343.      str db string
  344.   }
  345.  
  346.   strtbl startapps       ,\
  347.     <"/RD/1/PIC4",0>     ,\
  348.     <"/RD/1/DESKTOP",0>  ,\
  349.     <"/RD/1/MV",0>       ,\
  350.     <"/RD/1/JPEGVIEW",0> ,\
  351.     <"/RD/1/CPU",0>      ,\
  352.     <"/RD/1/SPANEL",0>   ,\
  353.     <"/RD/1/ICON2",0> ,\
  354.     <"/RD/1/VRR",0>
  355.  
  356. ;  header:            ; заголовок
  357. ;    db 'M E N U'
  358. ;  header_len = $ - header
  359.  
  360. ;  text:              ; текст на кнопках
  361. ;    db 'Background  '; 12
  362. ;    db 'Colors      '
  363. ;    db 'MeView      '
  364. ;    db 'Processes   '
  365. ;    db 'Panel setup '
  366. ;    db 'Icon manager'
  367.  
  368.   sz header, "KolibriOS"
  369.  
  370.   lsz text,\
  371.     en, 'Background  ',\
  372.     en, 'Colors      ',\
  373.     en, 'MeView      ',\
  374.     en, 'JpegView    ',\
  375.     en, 'Processes   ',\
  376.     en, 'Panel setup ',\
  377.     en, 'Icon manager',\
  378.     en, 'VRR         ',\
  379.     \
  380.     ru, 'Генератор обоев     ',\
  381.     ru, 'Системные цвета     ',\
  382.     ru, 'Просмотр BMP        ',\
  383.     ru, 'Просмотр JPEG       ',\
  384.     ru, 'Процессы            ',\
  385.     ru, 'Настройка панели    ',\
  386.     ru, 'Управление иконками ',\
  387.     ru, 'Настройка монитора  '
  388.  
  389. start_info:
  390.         .mode   dd      7
  391.                 dd      0
  392.         .params dd      0
  393.                 dd      0
  394.                 dd      0
  395.                 db      0
  396.                 dd      start_info.path
  397.  
  398. ; НЕИНИЦИАЛИЗИРОВАННЫЕ ДАННЫЕ
  399. UDATA
  400.   processes   dd ?              ; количество процессов в системе
  401.   curx1       dd ?              ; координаты курсора
  402.   cury1       dd ?
  403.   curx        dd ?              ; координаты окна меню
  404.   cury        dd ?
  405.  
  406.   menu_opened db ?              ; открыто меню или нет? (1-да, 0-нет)
  407.  
  408. align 4
  409. start_info.path rb 256
  410.  
  411.   sc       system_colors        ; системные цвета
  412.   procinfo process_information  ; информация о процессе
  413.  
  414.   rb 1024                       ; стэк для окна меню - хватит и 1 Кб
  415.   align 32
  416.   stack_wnd:
  417.  
  418.  
  419. MEOS_APP_END
  420. ; КОНЕЦ ПРОГРАММЫ