Subversion Repositories Kolibri OS

Rev

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