Subversion Repositories Kolibri OS

Rev

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