Subversion Repositories Kolibri OS

Rev

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