Subversion Repositories Kolibri OS

Rev

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