Subversion Repositories Kolibri OS

Rev

Rev 3068 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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