static HRESULT navigate_anchor(HTMLAnchorElement *This) { nsAString href_str, target_str; HTMLOuterWindow *window = NULL; nsresult nsres; HRESULT hres = E_FAIL; static const WCHAR _parentW[] = {'p','a','r','e','n','t',0}; static const WCHAR _selfW[] = {'_','s','e','l','f',0}; static const WCHAR _topW[] = {'_','t','o','p',0}; nsAString_Init(&target_str, NULL); nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str); if(NS_SUCCEEDED(nsres)) { const PRUnichar *target; nsAString_GetData(&target_str, &target); TRACE("target %s\n", debugstr_w(target)); if(*target && strcmpiW(target, _selfW)) { if(!strcmpiW(target, _topW)) { TRACE("target _top\n"); get_top_window(This->element.node.doc->basedoc.window, &window); }else if(!strcmpiW(target, _parentW)) { FIXME("Navigating to target _parent is not implemented\n"); nsAString_Finish(&target_str); return S_OK; }else { HTMLOuterWindow *top_window; get_top_window(This->element.node.doc->basedoc.window, &top_window); hres = get_frame_by_name(top_window, target, TRUE, &window); if(FAILED(hres) || !window) { hres = navigate_anchor_window(This, target); nsAString_Finish(&target_str); return hres; } } } } nsAString_Finish(&target_str); nsAString_Init(&href_str, NULL); nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); if(NS_SUCCEEDED(nsres)) { const PRUnichar *href; nsAString_GetData(&href_str, &href); if(*href) { if(!window) window = This->element.node.doc->basedoc.window; hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED); }else { TRACE("empty href\n"); hres = S_OK; } } nsAString_Finish(&href_str); return hres; }
HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window) { HTMLOuterWindow *top_window, *ret_window; const PRUnichar *target; HRESULT hres; static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0}; static const WCHAR _selfW[] = {'_','s','e','l','f',0}; static const WCHAR _topW[] = {'_','t','o','p',0}; *use_new_window = FALSE; nsAString_GetData(target_str, &target); TRACE("%s\n", debugstr_w(target)); if(!*target || !strcmpiW(target, _selfW)) { IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); return window; } if(!strcmpiW(target, _topW)) { get_top_window(window, &top_window); IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface); return top_window; } if(!strcmpiW(target, _parentW)) { if(!window->parent) { WARN("Window has no parent, treat as self\n"); IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); return window; } IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface); return window->parent; } get_top_window(window, &top_window); hres = get_frame_by_name(top_window, target, TRUE, &ret_window); if(FAILED(hres) || !ret_window) { *use_new_window = TRUE; return NULL; } IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface); return ret_window; }
void mouse_event(mouse_packet_t *packet) { if (packet->mouse_x != old_x || packet->mouse_y != old_y) { /* mouse moved */ if (old_leftbtn || packet->left_btn) { /* the user is dragging something! */ int dx, dy; win_info_t *win = get_top_window(); if (win && (drag_x != -1 || ( (int) old_x >= (int) win->x-4 && (int) old_y >= (int) win->y-22 && (int) old_x < (int) win->x+win->pixbuf->width+8 && (int) old_y < (int) win->y))) { /* the dragging is on the title bar */ if (drag_x == -1) { drag_x = old_x; drag_y = old_y; win_x = win->x; win_y = win->y; } if (last_x != -1) { dx = last_x - drag_x; dy = last_y - drag_y; hide_box(win_x-4 + dx, win_y-22 + dy, win->pixbuf->width+8, win->pixbuf->height+26); } dx = (last_x = packet->mouse_x) - drag_x; dy = (last_y = packet->mouse_y) - drag_y; show_box(win_x-4 + dx, win_y-22 + dy, win->pixbuf->width+8, win->pixbuf->height+26); } } draw_cursor(); } if (!old_leftbtn && packet->left_btn) { /* button pressed */ old_leftbtn = 1; if (drag_x == -1) { win_info_t *top; msg_t msg; wm_event_t event = {0}; /* change focus */ top = change_focus(old_x, old_y); if (top) { /* send event packet */ int rx = old_x - (top->x-4); int ry = old_y - (top->y-22); int close_x = (top->pixbuf->width+8)-26; int close_y = 3; int close_width = 20; int close_height = 16; event.prefix = PREFIX_WINMAN; if (rx >= close_x && ry >= close_y && rx < close_x + close_width && ry < close_y + close_height) { /* close button clicked */ event.type = WMEVENT_CLOSE; } else if (last_click == -1 || packet->time - last_click > 500) { /* simple click */ event.type = WMEVENT_CLICK; } else { /* double click */ event.type = WMEVENT_DOUBLE; } last_click = packet->time; event.id = top->wid; event.data[0] = old_x - top->x; event.data[1] = old_y - top->y; msg.buf = &event; msg.size = sizeof(wm_event_t); send(top->pid, &msg); } } } if (old_leftbtn && !packet->left_btn) { /* button released */ old_leftbtn = 0; if (drag_x != -1) { /* drop */ int dx, dy; win_info_t *win = get_top_window(); if (win) { dx = packet->mouse_x - drag_x; dy = packet->mouse_y - drag_y; win->x = win_x + dx; win->y = win_y + dy; update_screen(); } } last_x = -1; drag_x = -1; } }