void edit_set_number_of_lines(void *window, int numlin) { EDITINFO *einf; void *pdata; Window pwin; (void) get_window_type(*(Window*) window, &pwin, &pdata); (void) get_window_type(pwin, &pwin, &pdata); einf = (EDITINFO*) pdata; scrollbar_set(einf->scrollver, line_number(einf->info), numlin); }
/* * Exported function. Documented in scrollbar.h */ void scrollbar_mouse_drag_end(struct scrollbar *s, browser_mouse_state mouse, int x, int y) { struct scrollbar_msg_data msg; int val, drag_start_pos; assert(s->dragging); drag_start_pos = s->drag_start_pos; val = (s->horizontal ? x : y) - s->drag_start_coord; if (s->drag_content) val = -val; if (val != 0) scrollbar_set(s, drag_start_pos + val, !(s->drag_content)); s->dragging = false; s->drag_content = false; if (s->pair_drag) { s->pair_drag = false; drag_start_pos = s->pair->drag_start_pos; val = (s->pair->horizontal ? x : y) - s->pair->drag_start_coord; if (s->pair->drag_content) val = -val; if (val != 0) scrollbar_set(s->pair, drag_start_pos + val, !(s->pair->drag_content)); s->pair->dragging = false; s->pair->drag_content = false; } msg.scrollbar = s; msg.msg = SCROLLBAR_MSG_SCROLL_FINISHED; s->client_callback(s->client_data, &msg); }
/* * Exported function. Documented in scrollbar.h */ const char *scrollbar_mouse_action(struct scrollbar *s, browser_mouse_state mouse, int x, int y) { int x0, y0, x1, y1; int val; const char *status; bool h; /* we want mouse presses and mouse drags that were not started at the * scrollbar indication bar to be launching actions on the scroll area */ bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) || ((mouse & BROWSER_MOUSE_HOLDING_1) && (mouse & BROWSER_MOUSE_DRAG_ON) && !s->dragging)); bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) || ((mouse & BROWSER_MOUSE_HOLDING_2) && (mouse & BROWSER_MOUSE_DRAG_ON) && !s->dragging)); h = s->horizontal; x0 = 0; y0 = 0; x1 = h ? s->length : SCROLLBAR_WIDTH; y1 = h ? SCROLLBAR_WIDTH : s->length; if (!s->dragging && !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) { /* Not a drag and mouse outside scrollbar widget */ return NULL; } if (h) val = x; else val = y; if (s->dragging) { val -= s->drag_start_coord; if (s->drag_content) val = -val; if (val != 0) scrollbar_set(s, s->drag_start_pos + val, !(s->drag_content)); if (s->pair_drag) { scrollbar_mouse_action(s->pair, mouse, x, y); status = messages_get("ScrollBoth"); } else status = messages_get(h ? "ScrollH" : "ScrollV"); return status; } if (val < SCROLLBAR_WIDTH) { /* left/up arrow */ status = messages_get(h ? "ScrollLeft" : "ScrollUp"); if (but1) scrollbar_set(s, s->offset - SCROLLBAR_WIDTH, false); else if (but2) scrollbar_set(s, s->offset + SCROLLBAR_WIDTH, false); } else if (val < SCROLLBAR_WIDTH + s->bar_pos) { /* well between left/up arrow and bar */ status = messages_get(h ? "ScrollPLeft" : "ScrollPUp"); if (but1) scrollbar_set(s, s->offset - s->length, false); else if (but2) scrollbar_set(s, s->offset + s->length, false); } else if (val > s->length - SCROLLBAR_WIDTH) { /* right/down arrow */ status = messages_get(h ? "ScrollRight" : "ScrollDown"); if (but1) scrollbar_set(s, s->offset + SCROLLBAR_WIDTH, false); else if (but2) scrollbar_set(s, s->offset - SCROLLBAR_WIDTH, false); } else if (val > SCROLLBAR_WIDTH + s->bar_pos + s->bar_len) { /* well between right/down arrow and bar */ status = messages_get(h ? "ScrollPRight" : "ScrollPDown"); if (but1) scrollbar_set(s, s->offset + s->length, false); else if (but2) scrollbar_set(s, s->offset - s->length, false); } else { /* scrollbar position indication bar */ status = messages_get(h ? "ScrollH" : "ScrollV"); } if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2) && (val >= SCROLLBAR_WIDTH + s->bar_pos && val < SCROLLBAR_WIDTH + s->bar_pos + s->bar_len)) /* The mouse event is a drag start on the scrollbar position * indication bar. */ scrollbar_drag_start_internal(s, x, y, false, (mouse & BROWSER_MOUSE_DRAG_2) ? true : false); return status; }
void edit_open(void) { int x = INTERSPACE; int y = INTERSPACE; unsigned int w=4,h=4; int i; XSizeHints size_hints; EDITINFO *einf; state_window = NULL; if ( (einf = (EDITINFO *) malloc( sizeof(EDITINFO) )) == NULL) message(MP_ERROR, translate("Out of memory in edit.")); else { if (!state_open) if (!last_xpos && !last_ypos) { last_xpos = (display_width - last_width)/2; last_ypos = (display_height - last_height)/2; } einf->xpos = last_xpos; einf->ypos = last_ypos; einf->width = last_width; einf->height = last_height; einf->saved = MP_True; einf->auto_saved = MP_True; einf->view_mode = MP_False; einf->empty = MP_True; einf->iconized = MP_True; einf->shell = MP_False; einf->fini = MP_False; einf->strt = MP_False; einf->buflen=0; einf->pid=0; einf->prcsbuf=NULL; einf->win_id = XCreateWindow(display, root_window, einf->xpos, einf->ypos, einf->width, einf->height, BORDERWIDTH, CopyFromParent, InputOutput, visual, edit_mask, &edit_attr); if (state_open) size_hints.flags = USPosition | USSize | PMinSize; else size_hints.flags = PPosition | PSize | PMinSize; wm_hints.initial_state = ((iconic || as_icon) ? IconicState : NormalState); size_hints.min_width = size_hints.min_height = pos_y_with + SCROLLBARSIZE*3; XSetWMProperties(display, einf->win_id, NULL, NULL, NULL, 0, &size_hints, &wm_hints, &class_hints); wm_hints.initial_state = NormalState; set_protocols(einf->win_id); i=0; einf->headername = NULL; einf->filename = NULL; einf->pathname = NULL; einf->outputname = NULL; if (set_name(einf, NULL) && add_window(einf->win_id, MAINEDITWINDOW, root_window, (void *) einf, translate(helpname[EDITHELP]))) { while (i<NR_BUTTON && button_make(i, einf->win_id, translate(editbutton[perm[i]]), &x, y, 1, (void*) einf, helpname[edithelp[i]], NULL, NULL, edit_handle_button, edit_handle_button, edit_handle_button, NULL)) i++,x+=BINTERSPACE; w = sub_width(last_width); h = sub_height(last_height); if (i==NR_BUTTON) { einf->drawwin_id = XCreateWindow(display, einf->win_id, pos_x_with, pos_y_with, w-2, h-2, 1, CopyFromParent, InputOutput, visual, edit_mask, &edit_attr); if (add_window(einf->drawwin_id, EDITWINDOW, einf->win_id, NULL, translate(helpname[EDITSUBHELP]))) i++; } if (i==NR_BUTTON +1 && (einf->scrollhor = scrollbar_make(HORIZONTAL, einf->win_id, pos_x_with, pos_y_without, w, font_width(), edit_scrollto, (void*) einf))) i++; if (i==NR_BUTTON+2 && (einf->scrollver = scrollbar_make(VERTICAL, einf->win_id, pos_x_without, pos_y_with, h, line_height(), edit_scrollto, (void*) einf))) i++; } if (i<NR_BUTTON+3) { free(einf->headername); free(einf->pathname); free(einf->filename); XDestroyWindow(display, einf->win_id); destroy_window(einf->win_id); } else { is_opened = MP_True; scrollbar_set(einf->scrollver, 0, 1); scrollbar_set(einf->scrollhor, 0, 80); move_selection = !as_icon; einf->info = open_editwindow(&einf->drawwin_id, w-2, h-2); move_selection = MP_False; (void) window_changed(einf->info); number_icon++; number_open++; edit_is_open = MP_True; edit_iconized = (number_icon==number_open); state_window = einf; XMapSubwindows(display, einf->win_id); XMapWindow(display, einf->win_id); } } }
static nserror html_object_callback(hlcache_handle *object, const hlcache_event *event, void *pw) { struct content_html_object *o = pw; html_content *c = (html_content *) o->parent; int x, y; struct box *box; assert(c->base.status != CONTENT_STATUS_ERROR); box = o->box; if (box == NULL && event->type != CONTENT_MSG_ERROR) { return NSERROR_OK; } switch (event->type) { case CONTENT_MSG_LOADING: if (c->base.status != CONTENT_STATUS_LOADING && c->bw != NULL) content_open(object, c->bw, &c->base, box->object_params); break; case CONTENT_MSG_READY: if (content_can_reformat(object)) { /* TODO: avoid knowledge of box internals here */ content_reformat(object, false, box->max_width != UNKNOWN_MAX_WIDTH ? box->width : 0, box->max_width != UNKNOWN_MAX_WIDTH ? box->height : 0); /* Adjust parent content for new object size */ html_object_done(box, object, o->background); if (c->base.status == CONTENT_STATUS_READY || c->base.status == CONTENT_STATUS_DONE) content__reformat(&c->base, false, c->base.available_width, c->base.height); } break; case CONTENT_MSG_DONE: c->base.active--; LOG("%d fetches active", c->base.active); html_object_done(box, object, o->background); if (c->base.status != CONTENT_STATUS_LOADING && box->flags & REPLACE_DIM) { union content_msg_data data; if (!box_visible(box)) break; box_coords(box, &x, &y); data.redraw.x = x + box->padding[LEFT]; data.redraw.y = y + box->padding[TOP]; data.redraw.width = box->width; data.redraw.height = box->height; data.redraw.full_redraw = true; content_broadcast(&c->base, CONTENT_MSG_REDRAW, data); } break; case CONTENT_MSG_ERROR: hlcache_handle_release(object); o->content = NULL; if (box != NULL) { c->base.active--; LOG("%d fetches active", c->base.active); content_add_error(&c->base, "?", 0); html_object_failed(box, c, o->background); } break; case CONTENT_MSG_REDRAW: if (c->base.status != CONTENT_STATUS_LOADING) { union content_msg_data data = event->data; if (!box_visible(box)) break; box_coords(box, &x, &y); if (object == box->background) { /* Redraw request is for background */ css_fixed hpos = 0, vpos = 0; css_unit hunit = CSS_UNIT_PX; css_unit vunit = CSS_UNIT_PX; int width = box->padding[LEFT] + box->width + box->padding[RIGHT]; int height = box->padding[TOP] + box->height + box->padding[BOTTOM]; int t, h, l, w; /* Need to know background-position */ css_computed_background_position(box->style, &hpos, &hunit, &vpos, &vunit); w = content_get_width(box->background); if (hunit == CSS_UNIT_PCT) { l = (width - w) * hpos / INTTOFIX(100); } else { l = FIXTOINT(nscss_len2px(hpos, hunit, box->style)); } h = content_get_height(box->background); if (vunit == CSS_UNIT_PCT) { t = (height - h) * vpos / INTTOFIX(100); } else { t = FIXTOINT(nscss_len2px(vpos, vunit, box->style)); } /* Redraw area depends on background-repeat */ switch (css_computed_background_repeat( box->style)) { case CSS_BACKGROUND_REPEAT_REPEAT: data.redraw.x = 0; data.redraw.y = 0; data.redraw.width = box->width; data.redraw.height = box->height; break; case CSS_BACKGROUND_REPEAT_REPEAT_X: data.redraw.x = 0; data.redraw.y += t; data.redraw.width = box->width; break; case CSS_BACKGROUND_REPEAT_REPEAT_Y: data.redraw.x += l; data.redraw.y = 0; data.redraw.height = box->height; break; case CSS_BACKGROUND_REPEAT_NO_REPEAT: data.redraw.x += l; data.redraw.y += t; break; default: break; } data.redraw.object_width = box->width; data.redraw.object_height = box->height; /* Add offset to box */ data.redraw.x += x; data.redraw.y += y; data.redraw.object_x += x; data.redraw.object_y += y; content_broadcast(&c->base, CONTENT_MSG_REDRAW, data); break; } else { /* Non-background case */ if (hlcache_handle_get_content(object) == event->data.redraw.object) { int w = content_get_width(object); int h = content_get_height(object); if (w != 0) { data.redraw.x = data.redraw.x * box->width / w; data.redraw.width = data.redraw.width * box->width / w; } if (h != 0) { data.redraw.y = data.redraw.y * box->height / h; data.redraw.height = data.redraw.height * box->height / h; } data.redraw.object_width = box->width; data.redraw.object_height = box->height; } data.redraw.x += x + box->padding[LEFT]; data.redraw.y += y + box->padding[TOP]; data.redraw.object_x += x + box->padding[LEFT]; data.redraw.object_y += y + box->padding[TOP]; } content_broadcast(&c->base, CONTENT_MSG_REDRAW, data); } break; case CONTENT_MSG_REFRESH: if (content_get_type(object) == CONTENT_HTML) { /* only for HTML objects */ guit->misc->schedule(event->data.delay * 1000, html_object_refresh, o); } break; case CONTENT_MSG_LINK: /* Don't care about favicons that aren't on top level content */ break; case CONTENT_MSG_GETCTX: *(event->data.jscontext) = NULL; break; case CONTENT_MSG_SCROLL: if (box->scroll_x != NULL) scrollbar_set(box->scroll_x, event->data.scroll.x0, false); if (box->scroll_y != NULL) scrollbar_set(box->scroll_y, event->data.scroll.y0, false); break; case CONTENT_MSG_DRAGSAVE: { union content_msg_data msg_data; if (event->data.dragsave.content == NULL) msg_data.dragsave.content = object; else msg_data.dragsave.content = event->data.dragsave.content; content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, msg_data); } break; case CONTENT_MSG_SAVELINK: case CONTENT_MSG_POINTER: case CONTENT_MSG_SELECTMENU: case CONTENT_MSG_GADGETCLICK: /* These messages are for browser window layer. * we're not interested, so pass them on. */ content_broadcast(&c->base, event->type, event->data); break; case CONTENT_MSG_CARET: { union html_focus_owner focus_owner; focus_owner.content = box; switch (event->data.caret.type) { case CONTENT_CARET_REMOVE: case CONTENT_CARET_HIDE: html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner, true, 0, 0, 0, NULL); break; case CONTENT_CARET_SET_POS: html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner, false, event->data.caret.pos.x, event->data.caret.pos.y, event->data.caret.pos.height, event->data.caret.pos.clip); break; } } break; case CONTENT_MSG_DRAG: { html_drag_type drag_type = HTML_DRAG_NONE; union html_drag_owner drag_owner; drag_owner.content = box; switch (event->data.drag.type) { case CONTENT_DRAG_NONE: drag_type = HTML_DRAG_NONE; drag_owner.no_owner = true; break; case CONTENT_DRAG_SCROLL: drag_type = HTML_DRAG_CONTENT_SCROLL; break; case CONTENT_DRAG_SELECTION: drag_type = HTML_DRAG_CONTENT_SELECTION; break; } html_set_drag_type(c, drag_type, drag_owner, event->data.drag.rect); } break; case CONTENT_MSG_SELECTION: { html_selection_type sel_type; union html_selection_owner sel_owner; if (event->data.selection.selection) { sel_type = HTML_SELECTION_CONTENT; sel_owner.content = box; } else { sel_type = HTML_SELECTION_NONE; sel_owner.none = true; } html_set_selection(c, sel_type, sel_owner, event->data.selection.read_only); } break; default: break; } if (c->base.status == CONTENT_STATUS_READY && c->base.active == 0 && (event->type == CONTENT_MSG_LOADING || event->type == CONTENT_MSG_DONE || event->type == CONTENT_MSG_ERROR)) { /* all objects have arrived */ content__reformat(&c->base, false, c->base.available_width, c->base.height); content_set_done(&c->base); } /* If 1) the configuration option to reflow pages while objects are * fetched is set * 2) an object is newly fetched & converted, * 3) the box's dimensions need to change due to being replaced * 4) the object's parent HTML is ready for reformat, * 5) the time since the previous reformat is more than the * configured minimum time between reformats * then reformat the page to display newly fetched objects */ else if (nsoption_bool(incremental_reflow) && event->type == CONTENT_MSG_DONE && box != NULL && !(box->flags & REPLACE_DIM) && (c->base.status == CONTENT_STATUS_READY || c->base.status == CONTENT_STATUS_DONE) && (wallclock() > c->base.reformat_time)) { content__reformat(&c->base, false, c->base.available_width, c->base.height); } return NSERROR_OK; }