#include "system.h" #include #include #include #include #include "winlib.h" int draw_frame(window_t *win); static int draw_window(window_t *win); uint32_t main_cursor; uint32_t cursor_ns; uint32_t cursor_we; uint32_t cursor_nwse; uint32_t cursor_nesw; static pos_t old_pos; ctrl_t *mouse_capture = NULL; static link_t timers; static uint32_t realtime; static uint32_t wait_time; static uint32_t exp_time; static int need_update; #define LOAD_FROM_MEM 1 void adjust_frame(window_t *win); #include "control.inc" //#include "io.inc" #include "timer.inc" //#include "button.inc" //#include "scroller.inc" static window_t Window; void init_frame(window_t *win); window_t *create_window(char *caption, int style, int x, int y, int w, int h, handler_t handler) { int stride; ctx_t *ctx = &Window.client_ctx; if(handler==0) return 0; Window.handler = handler; Window.ctx = ctx; list_initialize(&Window.link); list_initialize(&Window.child); ctx->pixmap = user_alloc(1280*1024*4); if(!ctx->pixmap) { printf("not enough memory for context bitmap\n"); return NULL; }; stride = w*4; ctx->stride = stride; Window.rc.l = x; Window.rc.t = y; Window.rc.r = x + w; Window.rc.b = y + h; Window.w = w; Window.h = h; Window.caption_txt = caption; Window.style = style; Window.child_over = NULL; Window.child_focus = NULL; init_caption(&Window); init_panel(&Window); init_frame(&Window); send_message((ctrl_t*)&Window, MSG_SIZE, 0, 0); return &Window; }; int def_window_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2) { ctrl_t *child; window_t *win = (window_t*)ctrl; switch(msg) { case MSG_PAINT: draw_window(win); break; case 2: child = (ctrl_t*)win->child.next; while( &child->link != &win->child) { send_message(child, 2, arg1, arg2); child = (ctrl_t*)child->link.next; }; break; case MSG_MOUSEMOVE: child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16)); if( win->child_over ) { if(child == win->child_over) send_message(child, msg, 0, arg2); else send_message(win->child_over, MSG_MOUSELEAVE, 0, arg2); } else if( child ) send_message(child, MSG_MOUSEENTER, 0, arg2); win->child_over = child; if( child ) send_message(child,msg,0,arg2); else if(main_cursor != 0) { set_cursor(0); main_cursor = 0; } break; case MSG_SIZE: break; default: child = win_get_child(win, arg2 & 0xFFFF, (arg2>>16)); win->child_over = child; if(child) send_message(child, msg, 0, arg2); }; return 0; } static int draw_window(window_t *win) { ctrl_t *child; void *ctx; rect_t *rc = &win->client; draw_caption(&win->caption); draw_panel(&win->panel); // draw_frame(win); // child = (ctrl_t*)win->child.next; // while( &child->link != &win->child) // { // send_message(child, 1, 0, 0); // child = (ctrl_t*)child->link.next; // }; return 0; }; void blit_client(window_t *win) { int w, h; w = win->client.r - win->client.l; h = win->client.b - win->client.t; Blit(win->ctx->pixmap, win->client.l, win->client.t, 0, 0, w, h, w, h,win->ctx->stride); }; int show_window(window_t *win, int state) { win->win_state = state; draw_window(win); BeginDraw(); DrawWindow(win->rc.l, win->rc.t, win->w-1, win->h-1, NULL,0,0x41); EndDraw(); blit_caption(&win->caption); blit_panel(&win->panel); // blit_client(win); return 0; } void window_update_layout(window_t *win) { char proc_info[1024]; int new_w, new_h; uint8_t state; int winx, winy, winw, winh; // __asm__ __volatile__("int3"); get_proc_info(proc_info); winx = *(uint32_t*)(proc_info+34); winy = *(uint32_t*)(proc_info+38); winw = *(uint32_t*)(proc_info+42)+1; winh = *(uint32_t*)(proc_info+46)+1; state = *(uint8_t*)(proc_info+70); if(state & 2) { win->win_state = MINIMIZED; return; } if(state & 4) { win->win_state = ROLLED; return; }; if(state & 1) win->win_state = MAXIMIZED; else win->win_state = NORMAL; if( (winx != win->rc.l) || (winy != win->rc.t) ) { win->rc.l = winx; win->rc.t = winy; win->rc.r = winx + win->w; win->rc.b = winy + win->h; }; if( winw == win->w && winh == win->h) return; int old_size; int new_size; int stride; old_size = win->ctx->stride * win->h; old_size = (old_size+4095) & ~4095; new_size = winw*winh*4; new_size = (new_size+4095) & ~4095; stride = winw*4; // printf("update win size %d %d\n", winw, winh); if( new_size < old_size) user_unmap(win->ctx->pixmap, new_size, old_size-new_size); win->ctx->stride = stride; win->rc.r = winx + winw; win->rc.b = winy + winh; win->w = winw; win->h = winh; update_caption_size(win); update_panel_size(win); adjust_frame(win); send_message((ctrl_t*)win, MSG_SIZE, 0, 0); draw_window(win); }; int send_mouse_message(window_t *win, uint32_t msg) { ctrl_t *child; if(mouse_capture) return send_message(mouse_capture, msg, 0, old_pos.val); if(pt_in_rect(&win->caption.ctrl.rc, old_pos.x, old_pos.y)) { return send_message(&win->caption.ctrl, msg, 0, old_pos.val); } if(pt_in_rect(&win->panel.ctrl.rc, old_pos.x, old_pos.y)) { // old_pos.x-= win->panel.ctrl.rc.l; // old_pos.y-= win->panel.ctrl.rc.t; return send_message(&win->panel.ctrl, msg, 0, old_pos.val); } if(pt_in_rect(&win->client, old_pos.x, old_pos.y)) return send_message((ctrl_t*)win, msg, 0, old_pos.val); return send_message(&win->frame, msg, 0, old_pos .val); // if( ( old_pos.x < win->rc.r) && ( old_pos.y < win->rc.b)) // send_message((ctrl_t*)win, msg, 0, old_pos.val); }; void do_sys_draw(window_t *win) { // printf("%s win:%x\n", __FUNCTION__, win); window_update_layout(win); BeginDraw(); DrawWindow(0,0,0,0, NULL, 0x000000,0x41); EndDraw(); blit_caption(&win->caption); blit_panel(&win->panel); // blit_client(win); send_message((ctrl_t*)win, MSG_DRAW_CLIENT, 0, 0); need_update=0; }; static void do_sys_mouse(window_t *win) { static uint32_t mouse_click_time; static int mouse_action; static int old_buttons; int buttons; uint32_t wheels; uint32_t click_time; int action; pos_t pos; mouse_action = 0; pos = get_mouse_pos(); if(pos.val != old_pos.val) { mouse_action = 0x80000000; old_pos = pos; }; // printf("pos x%d y%d\n", pos.x, pos.y); buttons = get_mouse_buttons(); wheels = get_mouse_wheels(); if( wheels & 0xFFFF){ wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP; send_mouse_message(win, wheels); } if((action = (buttons ^ old_buttons))!=0) { mouse_action|= action<<3; mouse_action|= buttons & ~old_buttons; } old_buttons = buttons; if(mouse_action & 0x80000000) { DBG("mouse move \n\r"); send_mouse_message(win, MSG_MOUSEMOVE); }; if(mouse_action & 0x09) { if((mouse_action & 0x09)==0x09) { // printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y); click_time = get_tick_count(); if(click_time < mouse_click_time+35) { mouse_click_time = click_time; send_mouse_message(win,MSG_LBTNDBLCLK); } else { mouse_click_time = click_time; send_mouse_message(win,MSG_LBTNDOWN); }; } else { // printf("left button up \n\r"); send_mouse_message(win,MSG_LBTNUP); } }; if(mouse_action & 0x12) { if((mouse_action & 0x12)==0x12) { DBG("right button down \n\r"); send_mouse_message(win,MSG_RBTNDOWN); } else { DBG("right button up \n\r"); send_mouse_message(win,MSG_RBTNUP); }; }; if(mouse_action & 0x24) { if((mouse_action & 0x24)==0x24){ DBG("middle button down \n\r"); send_mouse_message(win,MSG_MBTNDOWN); } else { DBG("middle button up \n\r"); send_mouse_message(win,MSG_MBTNUP); }; }; }; void run_window(window_t *win) { int ev; oskey_t key; // buttons = get_mouse_buttons(); // wheels = get_mouse_wheels(); realtime = get_tick_count(); exp_time = -1; while(1) { wait_time = exp_time - realtime; ev = wait_for_event(wait_time); realtime = get_tick_count(); // if(exp_time < realtime) // exp_time = update_timers(realtime); switch(ev) { case MSG_PAINT: do_sys_draw(win); continue; case 2: key = get_key(); if( key.state == 0) send_message((ctrl_t*)win, ev, 0, key.code); continue; case 6: do_sys_mouse(win); continue; default: continue; }; }; } void render_time(void *render); void run_render(window_t *win, void *render) { int ev; oskey_t key; realtime = get_tick_count(); exp_time = -1; while(win->win_command != WIN_CLOSED) { wait_time = exp_time - realtime; ev = check_os_event(); realtime = get_tick_count(); // if(exp_time < realtime) // exp_time = update_timers(realtime); switch(ev) { case MSG_PAINT: do_sys_draw(win); break; case 2: key = get_key(); if( key.state == 0) send_message((ctrl_t*)win, ev, 0, key.code); break; case 6: do_sys_mouse(win); break; default: break; }; render_time(render); }; }; extern unsigned char res_cursor_ns[]; extern unsigned char res_cursor_we[]; extern unsigned char res_cursor_nwse[]; extern unsigned char res_cursor_nesw[]; int init_resources() { cursor_ns = load_cursor(res_cursor_ns, LOAD_FROM_MEM); cursor_we = load_cursor(res_cursor_we, LOAD_FROM_MEM); cursor_nwse = load_cursor(res_cursor_nwse, LOAD_FROM_MEM); cursor_nesw = load_cursor(res_cursor_nesw, LOAD_FROM_MEM); return 1; } void init_winlib(void) { __asm__ __volatile__( "int $0x40" ::"a"(40), "b"(0xC0000027)); init_resources(); list_initialize(&timers); }; ctx_t *get_window_ctx() { return &Window.client_ctx; }; void update_rect(ctrl_t *ctrl) { int ctx_w, ctx_h; int src_x, src_y; src_x = ctrl->rc.l - ctrl->ctx->offset_x; src_y = ctrl->rc.t - ctrl->ctx->offset_y; ctx_w = ctrl->parent->w; ctx_h = ctrl->parent->h; Blit(ctrl->ctx->pixmap, ctrl->rc.l, ctrl->rc.t, src_x, src_y, ctrl->w, ctrl->h, ctx_w, ctx_h, ctrl->ctx->stride); // need_update++; }; void Blit(void *bitmap, int dst_x, int dst_y, int src_x, int src_y, int w, int h, int src_w, int src_h, int stride) { volatile struct blit_call bc; bc.dstx = dst_x; bc.dsty = dst_y; bc.w = w; bc.h = h; bc.srcx = src_x; bc.srcy = src_y; bc.srcw = src_w; bc.srch = src_h; bc.stride = stride; bc.bitmap = bitmap; __asm__ __volatile__( "int $0x40" ::"a"(73),"b"(0),"c"(&bc.dstx)); }; ctrl_t *get_child(ctrl_t *ctrl, int x, int y) { ctrl_t *child = NULL; ctrl_t *tmp = (ctrl_t*)ctrl->child.next; while( &tmp->link != &ctrl->child ) { if(pt_in_rect(&tmp->rc, x, y)) { child = get_child(tmp, x, y); return child == NULL ? tmp : child; }; tmp = (ctrl_t*)tmp->link.next; }; return child; }; ctrl_t *capture_mouse(ctrl_t *newm) { ctrl_t *old = mouse_capture; mouse_capture = newm; __asm__ __volatile__( "int $0x40" ::"a"(40), "b"(0x80000027)); return old; } void release_mouse(void) { mouse_capture = NULL; __asm__ __volatile__( "int $0x40" ::"a"(40), "b"(0xC0000027)); }