Subversion Repositories Kolibri OS

Rev

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