Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #include "winlib.h"
  7.  
  8. #define DBG(format,...)
  9.  
  10. int draw_frame(window_t *win);
  11. static int draw_window(window_t *win);
  12.  
  13. uint32_t main_cursor;
  14. uint32_t cursor_ns;
  15. uint32_t cursor_we;
  16. uint32_t cursor_nwse;
  17. uint32_t cursor_nesw;
  18.  
  19. int win_font;
  20.  
  21. static window_t Window;
  22.  
  23. static pos_t    old_pos;
  24.  
  25. ctrl_t  *mouse_capture = NULL;
  26.  
  27. static link_t    timers;
  28. static uint32_t  realtime;
  29. static uint32_t  wait_time;
  30. static uint32_t  exp_time;
  31.  
  32. static int need_update;
  33.  
  34. #define LOAD_FROM_MEM                1
  35.  
  36.  
  37. void adjust_frame(window_t *win);
  38. void blit_panel(panel_t *panel);
  39. void update_panel_size(window_t *win);
  40. void update_caption_size(window_t *win);
  41.  
  42. //#include "timer.h"
  43. ctrl_t *win_get_child(window_t *win, int x, int y)
  44. {
  45.     ctrl_t *child = NULL;
  46.  
  47.     if( win )
  48.     {
  49.         if(pt_in_rect(&win->client, x, y))
  50.         {
  51.             ctrl_t *tmp = (ctrl_t*)win->child.next;
  52.  
  53.             while( &tmp->link != &win->child )
  54.             {
  55.                 if(pt_in_rect(&tmp->rc, x, y))
  56.                 {
  57.                     child = get_child(tmp, x, y);
  58.                     return child == NULL ? tmp : child;
  59.                 };
  60.                 tmp = (ctrl_t*)tmp->link.next;
  61.             };
  62.         }
  63.         else child = (ctrl_t*)(&win->frame);
  64.     };
  65.     return child;
  66. };
  67.  
  68.  
  69. void init_frame(window_t *win);
  70.  
  71. window_t *create_window(char *caption, int style, int x, int y,
  72.                           int w, int h, handler_t handler)
  73. {
  74.     char proc_info[1024];
  75.     int stride;
  76.  
  77. //    __asm__ __volatile__("int3");
  78.  
  79.  
  80. //    ctx_t *ctx = &Window.client_ctx;
  81.  
  82.     if(handler==0) return 0;
  83.  
  84.     BeginDraw();
  85.     DrawWindow(x, y, w, h,
  86.                NULL,0,0x41);
  87.     EndDraw();
  88.  
  89.     get_proc_info(proc_info);
  90.  
  91.     x = *(uint32_t*)(proc_info+34);
  92.     y = *(uint32_t*)(proc_info+38);
  93.     w = *(uint32_t*)(proc_info+42)+1;
  94.     h = *(uint32_t*)(proc_info+46)+1;
  95.  
  96.     Window.handler = handler;
  97.  //   Window.ctx = ctx;
  98.  
  99.     list_initialize(&Window.link);
  100.     list_initialize(&Window.child);
  101.  
  102.  
  103. //    Window.bitmap.width  = 1920;
  104. //    Window.bitmap.height = 1080;
  105. //    Window.bitmap.flags  = 0;
  106.  
  107.  //   if( create_bitmap(&Window.bitmap) )
  108.  //   {
  109.  //       printf("not enough memory for window bitmap\n");
  110.  //       return 0;
  111.   //  }
  112.  
  113.  //   ctx->pixmap   = &Window.bitmap;
  114.  //   ctx->offset_x = 0;
  115.  //   ctx->offset_y = 0;
  116.  
  117.     Window.rc.l = x;
  118.     Window.rc.t = y;
  119.     Window.rc.r = x + w;
  120.     Window.rc.b = y + h;
  121.  
  122.     Window.w = w;
  123.     Window.h = h;
  124.  
  125.     Window.caption_txt = caption;
  126.     Window.style = style;
  127.  
  128.     Window.child_over  = NULL;
  129.     Window.child_focus = NULL;
  130.  
  131.     init_caption(&Window);
  132.     init_panel(&Window);
  133.     init_frame(&Window);
  134.     send_message((ctrl_t*)&Window, MSG_SIZE, 0, 0);
  135.     return &Window;
  136. };
  137.  
  138.  
  139. int def_window_proc(ctrl_t  *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
  140. {
  141.     ctrl_t   *child;
  142.  
  143.     window_t  *win = (window_t*)ctrl;
  144.  
  145.     switch(msg)
  146.     {
  147.         case MSG_PAINT:
  148.             draw_window(win);
  149.             break;
  150.  
  151.         case 2:
  152.             child  = (ctrl_t*)win->child.next;
  153.             while( &child->link != &win->child)
  154.             {
  155.                 send_message(child, 2, arg1, arg2);
  156.                 child = (ctrl_t*)child->link.next;
  157.             };
  158.             break;
  159.  
  160.         case MSG_MOUSEMOVE:
  161.             child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16));
  162.             if( win->child_over )
  163.             {
  164.                 if(child == win->child_over)
  165.                     send_message(child, msg, 0, arg2);
  166.                 else
  167.                     send_message(win->child_over, MSG_MOUSELEAVE, 0, arg2);
  168.             }
  169.             else if( child )
  170.                 send_message(child, MSG_MOUSEENTER, 0, arg2);
  171.  
  172.             win->child_over = child;
  173.             if( child )
  174.                 send_message(child,msg,0,arg2);
  175.             else if(main_cursor != 0)
  176.             {
  177.                 set_cursor(0);
  178.                 main_cursor = 0;
  179.             }
  180.             break;
  181.  
  182.         case MSG_SIZE:
  183.             break;
  184.  
  185.         default:
  186.             child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16));
  187.             win->child_over = child;
  188.             if(child) send_message(child, msg, 0, arg2);
  189.     };
  190.  
  191.     return 0;
  192. }
  193.  
  194. static int draw_window(window_t *win)
  195. {
  196.     ctrl_t *child;
  197.     void   *ctx;
  198.     rect_t *rc = &win->client;
  199.  
  200.     draw_caption(&win->caption);
  201.     draw_panel(&win->panel);
  202.     send_message(win, MSG_DRAW_CLIENT,0,0);
  203.  
  204. //    draw_frame(win);
  205.  
  206. //    child  = (ctrl_t*)win->child.next;
  207.  
  208. //    while( &child->link != &win->child)
  209. //    {
  210. //        send_message(child, 1, 0, 0);
  211. //        child = (ctrl_t*)child->link.next;
  212. //    };
  213.  
  214.     return 0;
  215. };
  216.  
  217. void blit_client(window_t *win)
  218. {
  219.     ctx_t  *ctx = &win->ctx;
  220.     int w, h;
  221.  
  222.     w = win->client.r - win->client.l;
  223.     h = win->client.b - win->client.t;
  224.  
  225.     Blit(ctx->pixmap_data, win->client.l, win->client.t,
  226.          0, 0, w, h, w, h, ctx->pixmap_pitch);
  227. };
  228.  
  229.  
  230. int show_window(window_t *win, int state)
  231. {
  232.     win->win_state = state;
  233.  
  234.     draw_window(win);
  235.  
  236.     BeginDraw();
  237.     DrawWindow(win->rc.l, win->rc.t, win->w-1, win->h-1,
  238.                NULL,0,0x41);
  239.     EndDraw();
  240.  
  241.     blit_caption(&win->caption);
  242.     blit_panel(&win->panel);
  243. //    blit_client(win);
  244.     return 0;
  245. }
  246.  
  247. void window_update_layout(window_t *win)
  248. {
  249.     char proc_info[1024];
  250.  
  251.     int new_w, new_h;
  252.     uint8_t  state;
  253.  
  254.     int winx, winy, winw, winh;
  255.  
  256. //    __asm__ __volatile__("int3");
  257.  
  258.     get_proc_info(proc_info);
  259.  
  260.     winx = *(uint32_t*)(proc_info+34);
  261.     winy = *(uint32_t*)(proc_info+38);
  262.     winw = *(uint32_t*)(proc_info+42)+1;
  263.     winh = *(uint32_t*)(proc_info+46)+1;
  264.  
  265.     state  = *(uint8_t*)(proc_info+70);
  266.  
  267.     if(state & 2)
  268.     {   win->win_state = MINIMIZED;
  269.         return;
  270.     }
  271.     if(state & 4)
  272.     {
  273.         win->win_state = ROLLED;
  274.         return;
  275.     };
  276.  
  277.     if(state & 1)
  278.         state = MAXIMIZED;
  279.     else
  280.         state = NORMAL;
  281.  
  282.     if( (winx != win->rc.l) || (winy != win->rc.t) )
  283.     {
  284.         win->rc.l = winx;
  285.         win->rc.t = winy;
  286.         win->rc.r = winx + win->w;
  287.         win->rc.b = winy + win->h;
  288.     };
  289.  
  290. //    if( winw  == win->w &&
  291. //        winh  == win->h &&
  292. //        state == win->win_state)
  293. //        return;
  294.  
  295.     if(win->win_state != FULLSCREEN)
  296.         win->win_state = state;
  297.  
  298. #if 0
  299.     int old_size;
  300.     int new_size;
  301.     int pitch;
  302.  
  303.  
  304.     old_size = win->bitmap.pitch * win->bitmap.height;
  305.     old_size = (old_size+4095) & ~4095;
  306.  
  307.     pitch = ALIGN(win->w*4, 16);
  308.  
  309.     new_size = pitch * win->h;
  310.     new_size = (new_size+4095) & ~4095;
  311.  
  312.     if( new_size < old_size)
  313.         user_unmap(win->bitmap.data, new_size, old_size-new_size);
  314.  
  315.     win->bitmap.width = win->w;
  316.     win->bitmap.pitch = pitch;
  317. #endif
  318.  
  319.     win->rc.r = winx + winw;
  320.     win->rc.b = winy + winh;
  321.     win->w = winw;
  322.     win->h = winh;
  323.  
  324.     update_caption_size(win);
  325.     update_panel_size(win);
  326.     adjust_frame(win);
  327.  
  328.     send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
  329.     draw_window(win);
  330. };
  331.  
  332.  
  333. int send_mouse_message(window_t *win, uint32_t msg)
  334. {
  335.     ctrl_t *child;
  336.  
  337.     if(mouse_capture)
  338.         return send_message(mouse_capture, msg, 0, old_pos.val);
  339.  
  340.     if(pt_in_rect(&win->client, old_pos.x, old_pos.y))
  341.         return send_message((ctrl_t*)win, msg, 0, old_pos.val);
  342.  
  343.     if(win->win_state == FULLSCREEN)
  344.         return 0;
  345.  
  346.     if(pt_in_rect(&win->caption.ctrl.rc, old_pos.x, old_pos.y))
  347.     {
  348.         return send_message(&win->caption.ctrl, msg, 0, old_pos.val);
  349.     }
  350.  
  351.     if(pt_in_rect(&win->panel.ctrl.rc, old_pos.x, old_pos.y))
  352.     {
  353. //        old_pos.x-= win->panel.ctrl.rc.l;
  354. //        old_pos.y-= win->panel.ctrl.rc.t;
  355.         return send_message(&win->panel.ctrl, msg, 0, old_pos.val);
  356.     }
  357.  
  358.  
  359.     return send_message(&win->frame, msg, 0, old_pos .val);
  360.  
  361. //    if( ( old_pos.x < win->rc.r) && ( old_pos.y < win->rc.b))
  362. //        send_message((ctrl_t*)win, msg, 0, old_pos.val);
  363. };
  364.  
  365. void do_sys_draw(window_t *win)
  366. {
  367. //    printf("%s win:%x\n", __FUNCTION__, win);
  368.  
  369.     window_update_layout(win);
  370.  
  371.     BeginDraw();
  372.     DrawWindow(0,0,0,0, NULL, 0x000000,0x41);
  373.     EndDraw();
  374.  
  375.     send_message((ctrl_t*)win, MSG_DRAW_CLIENT, 0, 0);
  376.  
  377.     if(win->win_state == FULLSCREEN)
  378.     {
  379.         need_update=0;
  380.         return;
  381.     };
  382.  
  383.     blit_caption(&win->caption);
  384.     blit_panel(&win->panel);
  385.  
  386. //    blit_client(win);
  387.     need_update=0;
  388. };
  389.  
  390. static void do_sys_mouse(window_t *win)
  391. {
  392.     static uint32_t  mouse_click_time;
  393.     static int  mouse_action;
  394.     static int  old_buttons;
  395.     int         buttons;
  396.     uint32_t    wheels;
  397.     uint32_t    click_time;
  398.     int         action;
  399.  
  400.     pos_t       pos;
  401.  
  402.     mouse_action = 0;
  403.     pos = GetMousePos(POS_WINDOW);
  404.  
  405.     if(pos.val != old_pos.val)
  406.     {
  407.         mouse_action = 0x80000000;
  408.         old_pos = pos;
  409.     };
  410. //    printf("pos x%d y%d\n", pos.x, pos.y);
  411.  
  412.     buttons = GetMouseButtons();
  413.     wheels = get_mouse_wheels();
  414.  
  415.     if( wheels & 0xFFFF){
  416.         wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP;
  417.         send_mouse_message(win, wheels);
  418.     }
  419.  
  420.     if((action = (buttons ^ old_buttons))!=0)
  421.     {
  422.         mouse_action|= action<<3;
  423.         mouse_action|= buttons & ~old_buttons;
  424.     }
  425.     old_buttons = buttons;
  426.  
  427.     if(mouse_action & 0x80000000) {
  428.         DBG("mouse move \n\r");
  429.         send_mouse_message(win, MSG_MOUSEMOVE);
  430.     };
  431.  
  432.     if(mouse_action & 0x09)
  433.     {
  434.         if((mouse_action & 0x09)==0x09)
  435.         {
  436. //            printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y);
  437.             click_time = get_tick_count();
  438.             if(click_time < mouse_click_time+35) {
  439.                 mouse_click_time = click_time;
  440.                 send_mouse_message(win,MSG_LBTNDBLCLK);
  441.             }
  442.             else {
  443.               mouse_click_time = click_time;
  444.               send_mouse_message(win,MSG_LBTNDOWN);
  445.             };
  446.         }
  447.         else {
  448. //            printf("left button up \n\r");
  449.             send_mouse_message(win,MSG_LBTNUP);
  450.         }
  451.     };
  452.  
  453.     if(mouse_action & 0x12)
  454.     {
  455.         if((mouse_action & 0x12)==0x12) {
  456.             DBG("right button down \n\r");
  457.             send_mouse_message(win,MSG_RBTNDOWN);
  458.         }
  459.         else {
  460.             DBG("right button up \n\r");
  461.             send_mouse_message(win,MSG_RBTNUP);
  462.         };
  463.     };
  464.     if(mouse_action & 0x24)
  465.     {
  466.         if((mouse_action & 0x24)==0x24){
  467.             DBG("middle button down \n\r");
  468.             send_mouse_message(win,MSG_MBTNDOWN);
  469.         }
  470.         else {
  471.             DBG("middle button up \n\r");
  472.             send_mouse_message(win,MSG_MBTNUP);
  473.         };
  474.     };
  475.  
  476.  
  477. };
  478.  
  479.  
  480. void  run_window(window_t *win)
  481. {
  482.     int ev;
  483.     oskey_t   key;
  484.  
  485. //    buttons   = get_mouse_buttons();
  486. //    wheels    = get_mouse_wheels();
  487.     realtime  = get_tick_count();
  488.     exp_time  = -1;
  489.  
  490.     while(1)
  491.     {
  492.         wait_time = exp_time - realtime;
  493.  
  494.         ev = wait_for_event(wait_time);
  495.  
  496.         realtime = get_tick_count();
  497.  
  498. //        if(exp_time < realtime)
  499. //            exp_time = update_timers(realtime);
  500.  
  501.         switch(ev)
  502.         {
  503.             case MSG_PAINT:
  504.                 do_sys_draw(win);
  505.                 continue;
  506.  
  507.             case 2:
  508.                 printf("key pressed\n");
  509.                 key = get_key();
  510.                 if( key.state == 0)
  511.                     send_message((ctrl_t*)win, ev, 0, key.code);
  512.                 continue;
  513.  
  514.             case 3:
  515.                 printf("Button pressed\n");
  516.                 continue;
  517.  
  518.             case 6:
  519.                 do_sys_mouse(win);
  520.                 continue;
  521.  
  522.             default:
  523.                 printf("event %d\n", ev);
  524.                 continue;
  525.         };
  526.     };
  527. }
  528.  
  529. void render_time(void *render);
  530.  
  531. void  run_render(window_t *win, void *render)
  532. {
  533.     int ev;
  534.     oskey_t   key;
  535.     int button;
  536.  
  537.     realtime  = get_tick_count();
  538.     exp_time  = -1;
  539.  
  540.     while(win->win_command != WIN_CLOSED)
  541.     {
  542.         wait_time = exp_time - realtime;
  543.  
  544.         ev = check_os_event();
  545.  
  546.         realtime = get_tick_count();
  547.  
  548. //        if(exp_time < realtime)
  549. //            exp_time = update_timers(realtime);
  550.  
  551.         switch(ev)
  552.         {
  553.             case MSG_PAINT:
  554.                 do_sys_draw(win);
  555.                 break;
  556.  
  557.             case 2:
  558.                 key = get_key();
  559.                 if( key.state == 0)
  560.                     send_message((ctrl_t*)win, ev, 0, key.code);
  561.                 break;
  562.  
  563.             case 3:
  564.                 button = get_os_button();
  565.                 if(button == 1)
  566.                     win->win_command = WIN_CLOSED;
  567.                 break;
  568.  
  569.             case 6:
  570.                 do_sys_mouse(win);
  571.                 break;
  572.  
  573.             default:
  574.                 break;
  575.         };
  576.  
  577.         render_time(render);
  578.     };
  579. };
  580.  
  581.  
  582.  
  583. extern unsigned char res_cursor_ns[];
  584. extern unsigned char res_cursor_we[];
  585. extern unsigned char res_cursor_nwse[];
  586. extern unsigned char res_cursor_nesw[];
  587.  
  588. int init_resources()
  589. {
  590.     cursor_ns   = load_cursor(res_cursor_ns, LOAD_FROM_MEM);
  591.     cursor_we   = load_cursor(res_cursor_we, LOAD_FROM_MEM);
  592.     cursor_nwse = load_cursor(res_cursor_nwse, LOAD_FROM_MEM);
  593.     cursor_nesw = load_cursor(res_cursor_nesw, LOAD_FROM_MEM);
  594.  
  595.     win_font =  init_fontlib();
  596.  
  597.     return 1;
  598. }
  599.  
  600. int  fini_winlib()
  601. {
  602.     int ret;
  603.  
  604.     ret =  destroy_cursor(cursor_nesw);
  605.     ret |= destroy_cursor(cursor_nwse);
  606.     ret |= destroy_cursor(cursor_we);
  607.     ret |= destroy_cursor(cursor_ns);
  608.  
  609.     return ret;
  610. };
  611.  
  612.  
  613.  
  614. void  init_winlib(void)
  615. {
  616.     __asm__ __volatile__(
  617.     "int $0x40"
  618.     ::"a"(40), "b"(0xC0000027));
  619.     __asm__ __volatile__(
  620.     "int $0x40"
  621.     ::"a"(66), "b"(1),"c"(1));
  622.  
  623.     init_resources();
  624.     list_initialize(&timers);
  625. };
  626.  
  627. //ctx_t *get_window_ctx()
  628. //{
  629. //    return &Window.client_ctx;
  630. //};
  631.  
  632. void update_rect(ctrl_t *ctrl)
  633. {
  634.     ctx_t  *ctx = ctrl->ctx;
  635.  
  636.     int ctx_w, ctx_h;
  637.     int src_x, src_y;
  638.  
  639.     src_x = ctrl->rc.l - ctrl->ctx->offset_x;
  640.     src_y = ctrl->rc.t - ctrl->ctx->offset_y;
  641.  
  642.     ctx_w = ctrl->parent->w;
  643.     ctx_h = ctrl->parent->h;
  644.  
  645.     Blit(ctx->pixmap_data, ctrl->rc.l, ctrl->rc.t, src_x, src_y,
  646.          ctrl->w, ctrl->h, ctx_w, ctx_h, ctx->pixmap_pitch);
  647.  
  648. //    need_update++;
  649. };
  650.  
  651. ctrl_t *get_child(ctrl_t *ctrl, int x, int y)
  652. {
  653.     ctrl_t *child = NULL;
  654.  
  655.     ctrl_t *tmp = (ctrl_t*)ctrl->child.next;
  656.  
  657.     while( &tmp->link != &ctrl->child )
  658.     {
  659.         if(pt_in_rect(&tmp->rc, x, y))
  660.         {
  661.             child = get_child(tmp, x, y);
  662.             return child == NULL ? tmp : child;
  663.         };
  664.         tmp = (ctrl_t*)tmp->link.next;
  665.     };
  666.     return child;
  667. };
  668.  
  669. ctrl_t *capture_mouse(ctrl_t *newm)
  670. {
  671.     ctrl_t *old = mouse_capture;
  672.  
  673.     mouse_capture = newm;
  674.  
  675.     __asm__ __volatile__(
  676.     "int $0x40"
  677.     ::"a"(40), "b"(0x80000027));
  678.  
  679.     return old;
  680. }
  681.  
  682. void release_mouse(void)
  683. {
  684.     mouse_capture = NULL;
  685.     __asm__ __volatile__(
  686.     "int $0x40"
  687.     ::"a"(40), "b"(0xC0000027));
  688. }
  689.