bool ro_gui_history_click(wimp_pointer *pointer) { int x, y; wimp_window_state state; os_error *error; if (pointer->buttons != wimp_CLICK_SELECT && pointer->buttons != wimp_CLICK_ADJUST) /* return if not select or adjust click */ return true; state.w = history_window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return true; } x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; history_click(history_bw, history_current, x, y, pointer->buttons == wimp_CLICK_ADJUST); return true; }
void ro_treeview_mouse_at(wimp_pointer *pointer) { os_error *error; ro_treeview *tv; wimp_window_state state; int xpos, ypos; browser_mouse_state mouse; if (pointer->buttons & (wimp_CLICK_MENU)) return; tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); if (tv == NULL) { LOG(("NULL treeview block for window: 0x%x", (unsigned int) pointer->w)); return; } if (tv->drag == TREE_NO_DRAG) return; /* We know now that it's not a Menu click and the treeview thinks * that a drag is in progress. */ state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* Convert the returned mouse coordinates into NetSurf's internal * units. */ xpos = ((pointer->pos.x - state.visible.x0) + state.xscroll - tv->origin.x) / 2; ypos = ((state.visible.y1 - pointer->pos.y) - state.yscroll + tv->origin.y) / 2; /* Start to process the mouse click. */ mouse = ro_gui_mouse_drag_state(pointer->buttons, wimp_BUTTON_DOUBLE_CLICK_DRAG); tree_mouse_action(tv->tree, mouse, xpos, ypos); if (!(mouse & BROWSER_MOUSE_DRAG_ON)) { tree_drag_end(tv->tree, mouse, tv->drag_start.x, tv->drag_start.y, xpos, ypos); tv->drag = TREE_NO_DRAG; } if (tv->callbacks != NULL && tv->callbacks->toolbar_button_update != NULL) tv->callbacks->toolbar_button_update(); }
bool RiscosGui::createWindow(const char *title, int width, int height) { //First call the old createWindow function and then set the title. //In case there's some need to not setting the title. title = title; // TODO: set title string bool ret = createWindow(width, height); wimp_window_state state; os_error *error; state.w = _window; error = xwimp_get_window_state(&state); if (error) { log_debug("%s\n", error->errmess); return false; } state.visible.x1 = state.visible.x0 + (width * 2); state.visible.y1 = state.visible.y0 + (height * 2); error = xwimp_open_window((wimp_open *)&state); if (error) { log_debug("%s\n", error->errmess); return false; } return ret; }
void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) { wimp_window_state state; wimp_icon_state icon_state; os_error *error; state.w = w; icon_state.w = w; icon_state.i = i; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("MenuError", error->errmess); return; } error = xwimp_get_icon_state(&icon_state); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("MenuError", error->errmess); return; } ro_gui_menu_create(menu, state.visible.x0 + icon_state.icon.extent.x1 + 64, state.visible.y1 + icon_state.icon.extent.y1 - state.yscroll, w); current_menu_icon = i; }
void ro_gui_history_open(struct browser_window *bw, struct history *history, bool at_pointer) { int width, height; os_box box = {0, 0, 0, 0}; wimp_window_state state; os_error *error; assert(history); history_current = history; history_bw = bw; history_size(history, &width, &height); width *= 2; height *= 2; /* set extent */ box.x1 = width; box.y0 = -height; error = xwimp_set_extent(history_window, &box); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* open full size */ state.w = history_window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } state.visible.x0 = 0; state.visible.y0 = 0; state.visible.x1 = width; state.visible.y1 = height; state.next = wimp_HIDDEN; error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_dialog_open_persistent(bw->window->window, history_window, at_pointer); }
void RiscosGui::renderBuffer() { // bounding box is window-relative wimp_window_state state; os_error *error; state.w = _window; error = xwimp_get_window_state(&state); if (error) { log_debug("%s\n", error->errmess); } glue.render(state.visible.x0 / 2, _screen_height - (state.visible.y1 / 2), m_draw_minx, m_draw_miny, m_draw_maxx, m_draw_maxy); }
bool ro_gui_download_click(wimp_pointer *pointer) { struct gui_download_window *dw; dw = (struct gui_download_window *)ro_gui_wimp_event_get_user_data(pointer->w); if ((pointer->buttons & (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) && pointer->i == ICON_DOWNLOAD_ICON && !dw->error && !dw->saved) { const char *sprite = ro_gui_get_icon_string(pointer->w, pointer->i); int x = pointer->pos.x, y = pointer->pos.y; wimp_window_state wstate; wimp_icon_state istate; /* start the drag from the icon's exact location, rather than the pointer */ istate.w = wstate.w = pointer->w; istate.i = pointer->i; if (!xwimp_get_window_state(&wstate) && !xwimp_get_icon_state(&istate)) { x = (istate.icon.extent.x1 + istate.icon.extent.x0)/2 + wstate.visible.x0 - wstate.xscroll; y = (istate.icon.extent.y1 + istate.icon.extent.y0)/2 + wstate.visible.y1 - wstate.yscroll; } ro_mouse_drag_start(ro_gui_download_drag_end, NULL, NULL, NULL); download_window_current = dw; ro_gui_drag_icon(x, y, sprite); } else if (pointer->i == ICON_DOWNLOAD_DESTINATION) { char command[256] = "Filer_OpenDir "; char *dot; strncpy(command + 14, dw->path, 242); command[255] = 0; dot = strrchr(command, '.'); if (dot) { os_error *error; *dot = 0; error = xos_cli(command); if (error) { LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("MiscError", error->errmess); } } } return true; }
void ro_gui_dialog_open(wimp_w w) { int screen_x, screen_y, dx, dy; wimp_window_state open; os_error *error; /* find screen centre in os units */ ro_gui_screen_size(&screen_x, &screen_y); screen_x /= 2; screen_y /= 2; /* centre and open */ open.w = w; error = xwimp_get_window_state(&open); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } dx = (open.visible.x1 - open.visible.x0) / 2; dy = (open.visible.y1 - open.visible.y0) / 2; open.visible.x0 = screen_x - dx; open.visible.x1 = screen_x + dx; open.visible.y0 = screen_y - dy; open.visible.y1 = screen_y + dy; open.next = wimp_TOP; error = xwimp_open_window((wimp_open *) &open); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* Set the caret position */ ro_gui_set_caret_first(w); }
/** * Starts a drag for the save dialog * * \param pointer mouse position info from Wimp */ void ro_gui_save_start_drag(wimp_pointer *pointer) { if (pointer->buttons & (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) { const char *sprite = ro_gui_get_icon_string(pointer->w, pointer->i); int x = pointer->pos.x, y = pointer->pos.y; wimp_window_state wstate; wimp_icon_state istate; /* start the drag from the icon's exact location, rather than the pointer */ istate.w = wstate.w = pointer->w; istate.i = pointer->i; if (!xwimp_get_window_state(&wstate) && !xwimp_get_icon_state(&istate)) { x = (istate.icon.extent.x1 + istate.icon.extent.x0)/2 + wstate.visible.x0 - wstate.xscroll; y = (istate.icon.extent.y1 + istate.icon.extent.y0)/2 + wstate.visible.y1 - wstate.yscroll; } gui_current_drag_type = GUI_DRAG_SAVE; gui_save_sourcew = pointer->w; saving_from_dialog = true; gui_save_close_after = !(pointer->buttons & wimp_DRAG_ADJUST); ro_gui_drag_icon(x, y, sprite); } }
bool ro_gui_options_theme_initialise(wimp_w w) { wimp_window_state state; wimp_icon_state icon_state; os_error *error; struct theme_descriptor *theme_choice; struct toolbar_display *toolbar; /* only allow one instance for now*/ if (theme_pane) return false; error = xwimp_create_window(&theme_pane_definition, &theme_pane); if (error) { LOG(("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess)); return false; } state.w = w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); return false; } icon_state.w = w; icon_state.i = THEME_PANE_AREA; error = xwimp_get_icon_state(&icon_state); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); return false; } state.w = theme_pane; state.visible.x1 = state.visible.x0 + icon_state.icon.extent.x1 - 16 - ro_get_vscroll_width(theme_pane); state.visible.x0 += icon_state.icon.extent.x0 + 16; state.visible.y0 = state.visible.y1 + icon_state.icon.extent.y0 + 16; state.visible.y1 += icon_state.icon.extent.y1 - 28; LOG(("Y0 = %i, y1 = %i", icon_state.icon.extent.y0, icon_state.icon.extent.y1)); error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), w, wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_XORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_YORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_LS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_BS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_RS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_TS_EDGE_SHIFT); if (error) { LOG(("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess)); return false; } /* load themes */ ro_gui_options_theme_load(); /* set the current selection */ theme_choice = ro_gui_theme_find(option_theme); if (!theme_choice) theme_choice = ro_gui_theme_find("Aletheia"); for (toolbar = toolbars; toolbar; toolbar = toolbar->next) ro_gui_set_icon_selected_state(theme_pane, toolbar->icon_number, (toolbar->descriptor == theme_choice)); ro_gui_wimp_event_memorise(theme_pane); ro_gui_wimp_event_set_help_prefix(theme_pane, "HelpThemePConfig"); ro_gui_wimp_event_register_mouse_click(w, ro_gui_options_theme_click); ro_gui_wimp_event_register_cancel(w, THEME_CANCEL_BUTTON); ro_gui_wimp_event_register_ok(w, THEME_OK_BUTTON, ro_gui_options_theme_ok); ro_gui_wimp_event_set_help_prefix(w, "HelpThemeConfig"); ro_gui_wimp_event_memorise(w); return true; }
/** * Reflow a text area from the given line onwards * * \param ta Text area to reflow * \param line Line number to begin reflow on */ void ro_textarea_reflow(struct text_area *ta, unsigned int line) { rufl_code code; char *text; unsigned int len; size_t b_off; int x; char *space; unsigned int line_count = 0; os_box extent; os_error *error; /** \todo pay attention to line parameter */ /** \todo create horizontal scrollbar if needed */ ta->line_count = 0; if (!ta->lines) { ta->lines = malloc(LINE_CHUNK_SIZE * sizeof(struct line_info)); if (!ta->lines) { LOG(("malloc failed")); return; } } if (!(ta->flags & TEXTAREA_MULTILINE)) { /* Single line */ ta->lines[line_count].b_start = 0; ta->lines[line_count++].b_length = ta->text_len - 1; ta->line_count = line_count; return; } for (len = ta->text_len - 1, text = ta->text; len > 0; len -= b_off, text += b_off) { code = rufl_split(ta->font_family, ta->font_style, ta->font_size, text, len, ta->vis_width - MARGIN_LEFT - MARGIN_RIGHT, &b_off, &x); if (code != rufl_OK) { if (code == rufl_FONT_MANAGER_ERROR) LOG(("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess)); else LOG(("rufl_x_to_offset: 0x%x", code)); return; } if (line_count > 0 && line_count % LINE_CHUNK_SIZE == 0) { struct line_info *temp = realloc(ta->lines, (line_count + LINE_CHUNK_SIZE) * sizeof(struct line_info)); if (!temp) { LOG(("realloc failed")); return; } ta->lines = temp; } /* handle CR/LF */ for (space = text; space < text + b_off; space++) { if (*space == '\r' || *space == '\n') break; } if (space != text + b_off) { /* Found newline; use it */ ta->lines[line_count].b_start = text - ta->text; ta->lines[line_count++].b_length = space - text; /* CRLF / LFCR pair */ if (*space == '\r' && *(space + 1) == '\n') space++; else if (*space == '\n' && *(space + 1) == '\r') space++; b_off = space + 1 - text; if (len - b_off == 0) { /* reached end of input => add last line */ ta->lines[line_count].b_start = text + b_off - ta->text; ta->lines[line_count++].b_length = 0; } continue; } if (len - b_off > 0) { /* find last space (if any) */ for (space = text + b_off; space > text; space--) if (*space == ' ') break; if (space != text) b_off = space + 1 - text; } ta->lines[line_count].b_start = text - ta->text; ta->lines[line_count++].b_length = b_off; } ta->line_count = line_count; /* and now update extent */ extent.x0 = 0; extent.y1 = 0; extent.x1 = ta->vis_width; extent.y0 = -ta->line_height * line_count - ta->line_spacing; if (extent.y0 > (int)-ta->vis_height) /* haven't filled window yet */ return; error = xwimp_set_extent(ta->window, &extent); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); return; } /* Create vertical scrollbar if we don't already have one */ if (!ro_gui_wimp_check_window_furniture(ta->window, wimp_WINDOW_VSCROLL)) { wimp_window_state state; wimp_w parent; bits linkage; unsigned int vscroll_width; /* Save window parent & linkage flags */ state.w = ta->window; error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage); if (error) { LOG(("xwimp_get_window_state_and_nesting: 0x%x: %s", error->errnum, error->errmess)); return; } /* Now, attempt to create vertical scrollbar */ ro_gui_wimp_update_window_furniture(ta->window, wimp_WINDOW_VSCROLL, wimp_WINDOW_VSCROLL); /* Get new window state */ state.w = ta->window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); return; } /* Get scroll width */ vscroll_width = ro_get_vscroll_width(NULL); /* Shrink width by difference */ state.visible.x1 -= vscroll_width; /* and reopen window */ error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), parent, linkage); if (error) { LOG(("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess)); return; } /* finally, update visible width */ ta->vis_width -= vscroll_width; /* Now we've done that, we have to reflow the text area */ ro_textarea_reflow(ta, 0); } }
bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key) { wimp_w parent; wimp_window_state state; char *match_url; const char *url; int old_selection; int height; os_error *error; bool currently_open; assert(toolbar != NULL); parent = ro_toolbar_get_parent_window(toolbar); /* we must have a toolbar/url bar */ if (!ro_toolbar_get_display_url(toolbar) || (!nsoption_bool(url_suggestion))) { ro_gui_url_complete_close(); return false; } /* if we are currently active elsewhere, remove the previous window */ currently_open = ((parent == url_complete_parent) && (url_complete_matches_available > 0)); if (parent != url_complete_parent) ro_gui_url_complete_close(); /* forcibly open on down keys */ if ((!currently_open) && (url_complete_matched_string)) { switch (key) { case IS_WIMP_KEY | wimp_KEY_DOWN: case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: free(url_complete_matched_string); url_complete_matched_string = NULL; } } /* get the text to match */ url_complete_parent = parent; url = ro_toolbar_get_url(toolbar); match_url = (url != NULL) ? strdup(url) : NULL; if (match_url == NULL) { ro_gui_url_complete_close(); return false; } /* if the text to match has changed then update it */ if ((!url_complete_matched_string) || (strcmp(match_url, url_complete_matched_string))) { /* memorize the current matches */ int i; int lines = MAXIMUM_VISIBLE_LINES; if (lines > url_complete_matches_available) lines = url_complete_matches_available; if (url_complete_matches) { for (i = 0; i < MAXIMUM_VISIBLE_LINES; i++) { if (i < lines) { url_complete_redraw[i] = url_complete_matches[i]; } else { url_complete_redraw[i] = NULL; } } } /* our selection gets wiped */ error = xwimp_force_redraw(dialog_url_complete, 0, -(url_complete_matches_selection + 1) * 44, 65536, -url_complete_matches_selection * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } /* clear our state */ free(url_complete_original_url); free(url_complete_matched_string); url_complete_matched_string = match_url; url_complete_original_url = NULL; url_complete_matches_available = 0; url_complete_matches_selection = -1; url_complete_keypress_selection = -1; /* get some initial memory */ if (!url_complete_matches) { url_complete_matches = malloc(64 * sizeof(char *)); if (!url_complete_matches) { ro_gui_url_complete_close(); return false; } url_complete_matches_allocated = 64; } /* find matches */ url_complete_memory_exhausted = false; if (strlen(match_url) == 0) urldb_iterate_entries(url_complete_callback); else urldb_iterate_partial(match_url, url_complete_callback); if ((url_complete_memory_exhausted) || (url_complete_matches_available == 0)) { ro_gui_url_complete_close(); return false; } /* update the window */ state.w = parent; error = xwimp_get_window_state(&state); if (error) { LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return false; } url_complete_matches_reset = true; ro_gui_url_complete_resize(toolbar, PTR_WIMP_OPEN(&state)); url_complete_matches_reset = false; /* redraw the relevant bits of the window */ lines = MAXIMUM_VISIBLE_LINES; if (lines > url_complete_matches_available) lines = url_complete_matches_available; for (i = 0; i < lines; i++) { if (url_complete_redraw[i] != url_complete_matches[i]) { error = xwimp_force_redraw(dialog_url_complete, 0, -(i + 1) * 44, 65536, -i * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } } } } else { free(match_url); } /* handle keypresses */ if (!currently_open) return false; old_selection = url_complete_matches_selection; switch (key) { case IS_WIMP_KEY | wimp_KEY_UP: url_complete_matches_selection--; break; case IS_WIMP_KEY | wimp_KEY_DOWN: url_complete_matches_selection++; break; case IS_WIMP_KEY | wimp_KEY_PAGE_UP: url_complete_matches_selection -= MAXIMUM_VISIBLE_LINES; break; case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: url_complete_matches_selection += MAXIMUM_VISIBLE_LINES; break; case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: url_complete_matches_selection = 0; break; case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: url_complete_matches_selection = 65536; break; } if (url_complete_matches_selection > url_complete_matches_available - 1) url_complete_matches_selection = url_complete_matches_available - 1; else if (url_complete_matches_selection < -1) url_complete_matches_selection = -1; if (old_selection == url_complete_matches_selection) return false; error = xwimp_force_redraw(dialog_url_complete, 0, -(old_selection + 1) * 44, 65536, -old_selection * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } error = xwimp_force_redraw(dialog_url_complete, 0, -(url_complete_matches_selection + 1) * 44, 65536, -url_complete_matches_selection * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } if (old_selection == -1) { free(url_complete_original_url); url_complete_original_url = malloc(strlen(url) + 1); if (!url_complete_original_url) return false; strcpy(url_complete_original_url, url); } if (url_complete_matches_selection == -1) { ro_toolbar_set_url(toolbar, url_complete_original_url, true, false); } else { ro_toolbar_set_url(toolbar, nsurl_access(url_complete_matches[ url_complete_matches_selection]), true, false); free(url_complete_matched_string); url_complete_matched_string = strdup(nsurl_access( url_complete_matches[ url_complete_matches_selection])); } url_complete_keypress_selection = url_complete_matches_selection; /* auto-scroll */ state.w = dialog_url_complete; error = xwimp_get_window_state(&state); if (error) { LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return true; } if (state.yscroll < -(url_complete_matches_selection * 44)) state.yscroll = -(url_complete_matches_selection * 44); height = state.visible.y1 - state.visible.y0; if (state.yscroll - height > -((url_complete_matches_selection + 1) * 44)) state.yscroll = -((url_complete_matches_selection + 1) * 44) + height; error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return true; } return true; }
void ro_gui_options_theme_load(void) { os_error *error; os_box extent = { 0, 0, 0, 0 }; struct theme_descriptor *descriptor; struct toolbar_display *link; struct toolbar_display *toolbar_display; struct toolbar *toolbar; wimp_icon_create new_icon; wimp_window_state state; int parent_width, nested_y, min_extent, base_extent; int item_height; int *radio_icons, *radio_set; int theme_count; /* delete our old list and get/open a new one */ ro_gui_options_theme_free(); theme_list = ro_gui_theme_get_available(); ro_gui_theme_open(theme_list, true); /* create toolbars for each theme */ theme_count = 0; descriptor = theme_list; while (descriptor) { /* try to create a toolbar */ toolbar = ro_gui_theme_create_toolbar(descriptor, THEME_BROWSER_TOOLBAR); if (toolbar) { toolbar_display = calloc(sizeof(struct toolbar_display), 1); if (!toolbar_display) { LOG(("No memory for calloc()")); warn_user("NoMemory", 0); return; } toolbar_display->toolbar = toolbar; toolbar_display->descriptor = descriptor; if (!toolbars) { toolbars = toolbar_display; } else { link = toolbars; while (link->next) link = link->next; link->next = toolbar_display; } theme_count++; } descriptor = descriptor->next; } /* nest the toolbars */ state.w = theme_pane; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } parent_width = state.visible.x1 - state.visible.x0; min_extent = state.visible.y0 - state.visible.y1; nested_y = 0; base_extent = state.visible.y1 - state.yscroll; extent.x1 = parent_width; link = toolbars; new_icon.w = theme_pane; new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED | (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT); while (link) { /* update the toolbar */ item_height = 44 + 44 + 16; if (link->next) item_height += 16; ro_gui_theme_process_toolbar(link->toolbar, parent_width); extent.y0 = nested_y - link->toolbar->height - item_height; if (link->next) extent.y0 -= 16; if (extent.y0 > min_extent) extent.y0 = min_extent; xwimp_set_extent(theme_pane, &extent); ro_gui_set_icon_button_type(link->toolbar->toolbar_handle, ICON_TOOLBAR_URL, wimp_BUTTON_NEVER); /* create the descriptor icons and separator line */ new_icon.icon.extent.x0 = 8; new_icon.icon.extent.x1 = parent_width - 8; new_icon.icon.flags &= ~wimp_ICON_BORDER; new_icon.icon.flags |= wimp_ICON_SPRITE; new_icon.icon.extent.y1 = nested_y - link->toolbar->height - 8; new_icon.icon.extent.y0 = nested_y - link->toolbar->height - 52; new_icon.icon.data.indirected_text_and_sprite.text = (char *)&link->descriptor->name; new_icon.icon.data.indirected_text_and_sprite.size = strlen(link->descriptor->name) + 1; new_icon.icon.data.indirected_text_and_sprite.validation = theme_radio_validation; new_icon.icon.flags |= (wimp_BUTTON_RADIO << wimp_ICON_BUTTON_TYPE_SHIFT); xwimp_create_icon(&new_icon, &link->icon_number); new_icon.icon.flags &= ~wimp_ICON_SPRITE; new_icon.icon.extent.x0 = 52; new_icon.icon.extent.y1 -= 44; new_icon.icon.extent.y0 -= 44; new_icon.icon.data.indirected_text.text = (char *)&link->descriptor->author; new_icon.icon.data.indirected_text.size = strlen(link->descriptor->filename) + 1; new_icon.icon.data.indirected_text.validation = theme_null_validation; new_icon.icon.flags &= ~(wimp_BUTTON_RADIO << wimp_ICON_BUTTON_TYPE_SHIFT); xwimp_create_icon(&new_icon, 0); if (link->next) { new_icon.icon.flags |= wimp_ICON_BORDER; new_icon.icon.extent.x0 = -8; new_icon.icon.extent.x1 = parent_width + 8; new_icon.icon.extent.y1 -= 52; new_icon.icon.extent.y0 = new_icon.icon.extent.y1 - 8; new_icon.icon.data.indirected_text.text = theme_null_validation; new_icon.icon.data.indirected_text.validation = theme_line_validation; new_icon.icon.data.indirected_text.size = 1; xwimp_create_icon(&new_icon, 0); } /* nest the toolbar window */ state.w = link->toolbar->toolbar_handle; state.yscroll = 0; state.visible.y1 = nested_y + base_extent; state.visible.y0 = state.visible.y1 - link->toolbar->height + 2; xwimp_open_window_nested(PTR_WIMP_OPEN(&state), theme_pane, wimp_CHILD_LINKS_PARENT_WORK_AREA << wimp_CHILD_BS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_WORK_AREA << wimp_CHILD_TS_EDGE_SHIFT); /* continue processing */ nested_y -= link->toolbar->height + item_height; link = link->next; } /* set the icons as radios */ radio_icons = (int *)calloc(theme_count + 1, sizeof(int)); radio_set = radio_icons; for (link = toolbars; link; link = link->next) *radio_set++ = link->icon_number; *radio_set = -1; ro_gui_wimp_event_register_radio(theme_pane, radio_icons); /* update our display */ xwimp_force_redraw(theme_pane, 0, -16384, 16384, 16384); }
void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open) { os_box extent = { 0, 0, 0, 0 }; os_box url_extent; wimp_window_state toolbar_state; wimp_window_state state; os_error *error; int lines; int scroll_v = 0; /* only react to our window */ if (open->w != url_complete_parent) return; /* if there is no toolbar, or there is no URL bar shown, * or there are no URL matches, close it */ if (!ro_toolbar_get_display_url(toolbar) || (!url_complete_matches) || (url_complete_matches_available == 0)) { ro_gui_url_complete_close(); return; } /* get our current auto-complete window state for the scroll values */ state.w = dialog_url_complete; error = xwimp_get_window_state(&state); if (error) { LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return; } if (url_complete_matches_reset) state.yscroll = 0; /* move the window to the correct position */ toolbar_state.w = ro_toolbar_get_window(toolbar); error = xwimp_get_window_state(&toolbar_state); if (error) { LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return; } if (!ro_toolbar_get_url_field_extent(toolbar, &url_extent)) { LOG("Failed to read URL field extent."); return; } lines = url_complete_matches_available; extent.y0 = -(lines * 44); extent.x1 = 65536; error = xwimp_set_extent(dialog_url_complete, &extent); if (error) { LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return; } state.next = open->next; state.flags &= ~wimp_WINDOW_VSCROLL; state.flags &= ~(4095 << 16); /* clear bits 16-27 */ if (lines > MAXIMUM_VISIBLE_LINES) { lines = MAXIMUM_VISIBLE_LINES; scroll_v = ro_get_vscroll_width(NULL) - 2; state.flags |= wimp_WINDOW_VSCROLL; } state.visible.x0 = open->visible.x0 + 2 + url_extent.x0; state.visible.x1 = open->visible.x0 - 2 + url_extent.x1 - scroll_v; state.visible.y1 = open->visible.y1 - url_extent.y1 + 2; state.visible.y0 = state.visible.y1 - (lines * 44); if (state.visible.x1 + scroll_v > toolbar_state.visible.x1) state.visible.x1 = toolbar_state.visible.x1 - scroll_v; if (state.visible.x1 - state.visible.x0 < 0) { error = xwimp_close_window(dialog_url_complete); if (error) { LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } } else { error = xwimp_open_window_nested_with_flags(&state, (wimp_w)-1, 0); if (error) { LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return; } open->next = dialog_url_complete; } }
bool ro_gui_url_complete_click(wimp_pointer *pointer) { wimp_window_state state; os_error *error; int selection; struct gui_window *g; if ((mouse_x == pointer->pos.x) && (mouse_y == pointer->pos.y) && (!pointer->buttons)) return false; mouse_x = pointer->pos.x; mouse_y = pointer->pos.y; state.w = dialog_url_complete; error = xwimp_get_window_state(&state); if (error) { LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); return false; } selection = (state.visible.y1 - pointer->pos.y - state.yscroll) / 44; if (selection != url_complete_matches_selection) { int old_selection; if (url_complete_matches_selection == -1) { const char *url; g = ro_gui_window_lookup(url_complete_parent); if (!g) return false; url = ro_toolbar_get_url(g->toolbar); free(url_complete_original_url); url_complete_original_url = strdup(url); if (!url_complete_original_url) return false; } old_selection = url_complete_matches_selection; url_complete_matches_selection = selection; error = xwimp_force_redraw(dialog_url_complete, 0, -(old_selection + 1) * 44, 65536, -old_selection * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } error = xwimp_force_redraw(dialog_url_complete, 0, -(url_complete_matches_selection + 1) * 44, 65536, -url_complete_matches_selection * 44); if (error) { LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } } if (!pointer->buttons) return true; /* find owning window */ g = ro_gui_window_lookup(url_complete_parent); if (!g) return false; /* Select sets the text and launches */ if (pointer->buttons == wimp_CLICK_SELECT) { ro_toolbar_set_url(g->toolbar, nsurl_access(url_complete_matches[ url_complete_matches_selection]), true, false); /** \todo The interaction of components here is hideous */ /* Do NOT make any attempt to use any of the global url * completion variables after this call to browser_window_navigate. * They will be invalidated by (at least): * + ro_gui_window_set_url * + destruction of (i)frames within the current page * Any attempt to use them will probably result in a crash. */ browser_window_navigate(g->bw, url_complete_matches[url_complete_matches_selection], NULL, BW_NAVIGATE_HISTORY, NULL, NULL, NULL); ro_gui_url_complete_close(); /* Adjust just sets the text */ } else if (pointer->buttons == wimp_CLICK_ADJUST) { ro_toolbar_set_url(g->toolbar, nsurl_access(url_complete_matches[ url_complete_matches_selection]), true, false); ro_gui_url_complete_keypress(g->toolbar, 0); } return true; }
static bool ro_treeview_mouse_click(wimp_pointer *pointer) { os_error *error; ro_treeview *tv; wimp_window_state state; int xpos, ypos; browser_mouse_state mouse; bool handled = false; tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); if (tv == NULL) { LOG(("NULL treeview block for window: 0x%x", (unsigned int) pointer->w)); return false; } state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return false; } /* Convert the returned mouse coordinates into NetSurf's internal * units. */ xpos = ((pointer->pos.x - state.visible.x0) + state.xscroll - tv->origin.x) / 2; ypos = ((state.visible.y1 - pointer->pos.y) - state.yscroll + tv->origin.y) / 2; /* Start to process the mouse click. * * Select and Adjust are processed normally. To get filer-like operation * with selections, Menu clicks are passed to the treeview first as * Select if there are no selected nodes in the tree. */ mouse = 0; if (pointer->buttons == wimp_CLICK_MENU) { if (!tree_node_has_selection(tree_get_root(tv->tree))) mouse |= BROWSER_MOUSE_CLICK_1; } else { mouse = ro_gui_mouse_click_state(pointer->buttons, wimp_BUTTON_DOUBLE_CLICK_DRAG); /* Give the window input focus on Select-clicks. This wouldn't * be necessary if the core used the RISC OS caret. */ if (mouse & BROWSER_MOUSE_CLICK_1) xwimp_set_caret_position(tv->w, -1, -100, -100, 32, -1); } if (mouse != 0) { handled = tree_mouse_action(tv->tree, mouse, xpos, ypos); tv->drag = tree_drag_status(tv->tree); if (tv->drag != TREE_NO_DRAG) { tv->drag_start.x = xpos; tv->drag_start.y = ypos; } /* If it's a visible drag, start the RO side of the visible * effects. */ if (tv->drag == TREE_SELECT_DRAG || tv->drag == TREE_MOVE_DRAG) ro_treeview_drag_start(tv, pointer, &state); if (tv->callbacks != NULL && tv->callbacks->toolbar_button_update != NULL) tv->callbacks->toolbar_button_update(); } /* Special actions for some mouse buttons. Adjust closes the dialog; * Menu opens a menu. For the latter, we assume that the owning module * will have attached a window menu to our parent window with the auto * flag unset (so that we can fudge the selection above). If it hasn't, * the call will quietly fail. * * \TODO -- Adjust-click close isn't a perfect copy of what the RO * version did: adjust clicks anywhere close the tree, and * selections persist. */ switch(pointer->buttons) { case wimp_CLICK_ADJUST: if (handled) ro_gui_dialog_close(tv->w); break; case wimp_CLICK_MENU: ro_gui_wimp_event_process_window_menu_click(pointer); break; } return true; }
void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data) { int x, y; int width; const char *url; wimp_window_state state; wimp_icon_state ic; os_box box = {0, 0, 0, 0}; os_error *error; LOG(("Mouse at...")); /* If the mouse hasn't moved, or if we don't want tooltips, exit */ if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || !nsoption_bool(history_tooltip)) return; /* Update mouse position */ mouse_x = pointer->pos.x; mouse_y = pointer->pos.y; /* Find history tree entry under mouse */ state.w = history_window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; url = history_position_url(history_current, x, y); if (!url) { /* not over a tree entry => close tooltip window. */ error = xwimp_close_window(dialog_tooltip); if (error) { LOG(("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } return; } /* get width of string */ error = xwimptextop_string_width(url, strlen(url) > 256 ? 256 : strlen(url), &width); if (error) { LOG(("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_set_icon_string(dialog_tooltip, 0, url, true); /* resize icon appropriately */ ic.w = dialog_tooltip; ic.i = 0; error = xwimp_get_icon_state(&ic); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } error = xwimp_resize_icon(dialog_tooltip, 0, ic.icon.extent.x0, ic.icon.extent.y0, width + 16, ic.icon.extent.y1); if (error) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } state.w = dialog_tooltip; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* update window extent */ box.x1 = width + 16; box.y0 = -36; error = xwimp_set_extent(dialog_tooltip, &box); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* set visible area */ state.visible.x0 = pointer->pos.x + 24; state.visible.y0 = pointer->pos.y - 22 - 36; state.visible.x1 = pointer->pos.x + 24 + width + 16; state.visible.y1 = pointer->pos.y - 22; state.next = wimp_TOP; /* open window */ error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } }
void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, osbool more) { os_error *error; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &ro_plotters }; while (more) { ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; if (tv != NULL && tv->tree != NULL) { struct rect clip; tree_draw(tv->tree, tv->origin.x/2, -(tv->origin.y/2), (redraw->clip.x0 -(ro_plot_origin_x+tv->origin.x))/2, ((ro_plot_origin_y+tv->origin.y) -redraw->clip.y1)/2, (redraw->clip.x1 - redraw->clip.x0)/2, (redraw->clip.y1 - redraw->clip.y0)/2, &ctx); /* Put the graphcis window back how the Wimp set it. */ clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; ro_plotters.clip(&clip); } error = xwimp_get_rectangle(redraw, &more); if (error) { LOG(("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } } } /** * Callback to notify us of a new overall tree size. * * \param tree The tree being resized. * \param width The new width of the window. * \param height The new height of the window. * \param *pw The treeview object to be resized. */ void ro_treeview_resized(struct tree *tree, int width, int height, void *pw) { if (pw != NULL) { ro_treeview *tv = (ro_treeview *) pw; /* Store the width and height in terms of RISC OS work area. */ tv->size.x = width * 2; tv->size.y = -(height * 2); /* Resize the window. */ ro_treeview_set_window_extent(tv, tv->size.x, tv->size.y); } } /** * Callback to request that a section of the tree is scrolled into view. * * \param y The Y coordinate of top of the area in NS units. * \param height The height of the area in NS units. * \param *pw The treeview object affected. */ void ro_treeview_scroll_visible(int y, int height, void *pw) { if (pw != NULL) { ro_treeview *tv = (ro_treeview *) pw; os_error *error; wimp_window_state state; int visible_t, visible_b; int request_t, request_b; state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* Work out top and bottom of both the currently visible and * the required areas, in terms of the RO work area. */ visible_t = state.yscroll; visible_b = state.yscroll - (state.visible.y1 - state.visible.y0); request_t = -(2 * y);// - tv->origin.y; request_b = -(2 * (y + height));// - tv->origin.y; /* If the area is outside the visible window, then scroll it * in to view. */ if (request_t > visible_t || request_b < visible_b) { if (request_t > visible_t) { state.yscroll = request_t; } else if (request_b < visible_b) { state.yscroll = request_b + tv->origin.y + (state.visible.y1 - state.visible.y0); /* If the required area is bigger than the * visible extent, then align to the top and * let the bottom disappear out of view. */ if (state.yscroll < request_t) state.yscroll = request_t; } error = xwimp_open_window((wimp_open *) &state); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } } } } /** * Callback to return the tree window dimensions to the treeview system. * * \param *width Return the window width. * \param *height Return the window height. * \param *pw The treeview object to use. */ void ro_treeview_get_window_dimensions(int *width, int *height, void *pw) { if (pw != NULL && (width != NULL || height != NULL)) { ro_treeview *tv = (ro_treeview *) pw; os_error *error; wimp_window_state state; state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } if (width != NULL) *width = (state.visible.x1 - state.visible.x0) / 2; if (height != NULL) *height = (state.visible.y1 - state.visible.y0) / 2; } } /** * Resize the RISC OS window extent of a treeview. * * \param *tv The RISC OS treeview object to resize. * \param width The new width of the work area, in RO units. * \param height The new height of the work area, in RO units. */ void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height) { if (tv != NULL) { os_error *error; os_box extent; wimp_window_state state; int new_x, new_y; int visible_x, visible_y; int new_x_scroll, new_y_scroll; /* Calculate the new window extents, in RISC OS units. */ new_x = width + tv->origin.x; new_y = height + tv->origin.y; /* Get details of the existing window, and start to sanity * check the new extents. */ state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* If the extent is smaller than the current visible area, * then extend it so that it matches the visible area. */ if (new_x < (state.visible.x1 - state.visible.x0)) new_x = state.visible.x1 - state.visible.x0; if (new_y > (state.visible.y0 - state.visible.y1)) new_y = state.visible.y0 - state.visible.y1; /* Calculate the maximum visible coordinates of the existing * window. */ visible_x = state.xscroll + (state.visible.x1 - state.visible.x0); visible_y = state.yscroll + (state.visible.y0 - state.visible.y1); /* If the window is currently open, and the exising visible * area is bigger than the new extent, then we need to reopen * the window in an appropriare position before setting the * new extent. */ if ((state.flags & wimp_WINDOW_OPEN) && (visible_x > new_x || visible_y < new_y)) { new_x_scroll = state.xscroll; new_y_scroll = state.yscroll; if (visible_x > new_x) new_x_scroll = new_x - (state.visible.x1 - state.visible.x0); if (visible_y < new_y) new_y_scroll = new_y - (state.visible.y0 - state.visible.y1); if (new_x_scroll < 0) { state.visible.x1 -= new_x_scroll; state.xscroll = 0; } else { state.xscroll = new_x_scroll; } if (new_y_scroll > 0) { state.visible.y0 += new_y_scroll; state.yscroll = 0; } else { state.yscroll = new_y_scroll; } error = xwimp_open_window((wimp_open *) &state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* \todo -- Not sure if we need to reattach the * toolbar here: the nested wimp seems to take care * of it for us? */ } /* Now that the new extent fits into the visible window, we * can resize the work area. If we succeed, the values are * recorded to save having to ask the Wimp for them * each time. */ extent.x0 = 0; extent.y0 = new_y; extent.x1 = new_x; extent.y1 = 0; error = xwimp_set_extent(tv->w, &extent); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } tv->extent.x = new_x; tv->extent.y = new_y; } } /** * Handle RISC OS Window Open events for a treeview window. * * \param *open Pointer to the Window Open Event block. */ static void ro_treeview_open(wimp_open *open) { ro_treeview *tv; os_error *error; os_box extent; int width, height; tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(open->w); if (tv == NULL) { LOG(("NULL treeview block for window: ox%x", (unsigned int) open->w)); return; } /* Calculate the window work area. It must be at least the same as * the current visible area of the window, and needs to contain the * tree as defined by size.x + offset.x and size.y + offset.y (note * that the offset.y should be set to cover any toolbar, so we can * ignore the size of that). */ width = open->visible.x1 - open->visible.x0; height = open->visible.y0 - open->visible.y1; if (tv->size.x != 0 && width < (tv->origin.x + tv->size.x)) width = (tv->origin.x + tv->size.x); if (tv->size.y != 0 && height > (tv->size.y + tv->origin.y)) height = (tv->size.y + tv->origin.y); if (width != tv->extent.x || height != tv->extent.y) { extent.x0 = 0; extent.y0 = height; extent.x1 = width; extent.y1 = 0; error = xwimp_set_extent(tv->w, &extent); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } tv->extent.x = width; tv->extent.y = height; } /* \todo -- Might need to add vertical scrollbar hiding back in here? */ error = xwimp_open_window(open); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } if (tv->tb) ro_toolbar_process(tv->tb, -1, false); }
void gui_cert_verify(const char *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw) { struct ro_sslcert *sslcert_window; wimp_window_state state; wimp_icon_state istate; wimp_window_info info; os_error *error; bool set_extent; assert(certs); sslcert_window = malloc(sizeof(struct ro_sslcert)); if (sslcert_window == NULL) { LOG(("Failed to allocate memory for SSL Cert Dialog")); return; } /* Create the SSL window and its pane. */ error = xwimp_create_window(ro_gui_cert_dialog_template, &(sslcert_window->window)); if (error) { LOG(("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess)); free(sslcert_window); return; } error = xwimp_create_window(ro_gui_cert_tree_template, &(sslcert_window->pane)); if (error) { LOG(("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess)); free(sslcert_window); return; } /* Create the SSL data and build a tree from it. */ sslcert_window->tv = ro_treeview_create(sslcert_window->pane, NULL, NULL, sslcert_get_tree_flags()); if (sslcert_window->tv == NULL) { LOG(("Failed to allocate treeview")); free(sslcert_window); return; } sslcert_window->data = sslcert_create_session_data(num, url, cb, cbpw); sslcert_load_tree(ro_treeview_get_tree(sslcert_window->tv), certs, sslcert_window->data); tree_set_redraw(ro_treeview_get_tree(sslcert_window->tv), true); /* Set up the certificate window event handling. * * (The action buttons are registered as button events, not OK and * Cancel, as both need to carry out actions.) */ ro_gui_wimp_event_set_user_data(sslcert_window->window, sslcert_window); ro_gui_wimp_event_register_close_window(sslcert_window->window, ro_gui_cert_close_window); ro_gui_wimp_event_register_button(sslcert_window->window, ICON_SSL_REJECT, ro_gui_cert_reject); ro_gui_wimp_event_register_button(sslcert_window->window, ICON_SSL_ACCEPT, ro_gui_cert_accept); ro_gui_dialog_open_persistent(NULL, sslcert_window->window, false); /* Nest the tree window inside the pane window. To do this, we: * - Get the current pane extent, * - Get the parent window position and the location of the pane- * locating icon inside it, * - Set the visible area of the pane to suit, * - Check that the pane extents are OK for this visible area, and * increase them if necessary, * - Before finally opening the pane as a nested part of the parent. */ info.w = sslcert_window->pane; error = xwimp_get_window_info_header_only(&info); if (error) { ro_gui_cert_release_window(sslcert_window); LOG(("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess)); return; } state.w = sslcert_window->window; error = xwimp_get_window_state(&state); if (error) { ro_gui_cert_release_window(sslcert_window); LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); return; } istate.w = sslcert_window->window; istate.i = ICON_SSL_PANE; error = xwimp_get_icon_state(&istate); if (error) { ro_gui_cert_release_window(sslcert_window); LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); return; } state.w = sslcert_window->pane; state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - 20 - ro_get_vscroll_width(sslcert_window->pane); state.visible.x0 += istate.icon.extent.x0 + 20; state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + 20 + ro_get_hscroll_height(sslcert_window->pane); state.visible.y1 += istate.icon.extent.y1 - 32; set_extent = false; if ((info.extent.x1 - info.extent.x0) < (state.visible.x1 - state.visible.x0)) { info.extent.x0 = 0; info.extent.x1 = state.visible.x1 - state.visible.x0; set_extent = true; } if ((info.extent.y1 - info.extent.y0) < (state.visible.y1 - state.visible.y0)) { info.extent.y1 = 0; info.extent.x1 = state.visible.y0 - state.visible.y1; set_extent = true; } if (set_extent) { error = xwimp_set_extent(sslcert_window->pane, &(info.extent)); if (error) { ro_gui_cert_release_window(sslcert_window); LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); return; } } error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), sslcert_window->window, wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_XORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_YORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_LS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_RS_EDGE_SHIFT); if (error) { ro_gui_cert_release_window(sslcert_window); LOG(("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess)); ro_gui_cert_release_window(sslcert_window); return; } ro_treeview_set_origin(sslcert_window->tv, 0, 0); }
void ro_gui_history_redraw(wimp_draw *redraw) { osbool more; os_error *error; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &ro_plotters }; error = xwimp_redraw_window(redraw, &more); if (error) { LOG(("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } while (more) { ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; history_redraw(history_current, &ctx); error = xwimp_get_rectangle(redraw, &more); if (error) { LOG(("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } } } /** * Handle mouse movements over the history window. */ void ro_gui_history_mouse_at(wimp_pointer *pointer) { int x, y; int width; const char *url; wimp_window_state state; wimp_icon_state ic; os_box box = {0, 0, 0, 0}; os_error *error; /* If the mouse hasn't moved, or if we don't want tooltips, exit */ if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || !nsoption_bool(history_tooltip)) return; /* Update mouse position */ mouse_x = pointer->pos.x; mouse_y = pointer->pos.y; /* Find history tree entry under mouse */ state.w = history_window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; url = history_position_url(history_current, x, y); if (!url) { /* not over a tree entry => close tooltip window. */ error = xwimp_close_window(dialog_tooltip); if (error) { LOG(("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } return; } /* get width of string */ error = xwimptextop_string_width(url, strlen(url) > 256 ? 256 : strlen(url), &width); if (error) { LOG(("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_set_icon_string(dialog_tooltip, 0, url, true); /* resize icon appropriately */ ic.w = dialog_tooltip; ic.i = 0; error = xwimp_get_icon_state(&ic); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } error = xwimp_resize_icon(dialog_tooltip, 0, ic.icon.extent.x0, ic.icon.extent.y0, width + 16, ic.icon.extent.y1); if (error) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } state.w = dialog_tooltip; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* update window extent */ box.x1 = width + 16; box.y0 = -36; error = xwimp_set_extent(dialog_tooltip, &box); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* set visible area */ state.visible.x0 = pointer->pos.x + 24; state.visible.y0 = pointer->pos.y - 22 - 36; state.visible.x1 = pointer->pos.x + 24 + width + 16; state.visible.y1 = pointer->pos.y - 22; state.next = wimp_TOP; /* open window */ error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } }
/** * Set the caret's position * * \param self Text area * \param x X position of caret on the screen * \param y Y position of caret on the screen */ void ro_textarea_set_caret_xy(uintptr_t self, int x, int y) { struct text_area *ta; wimp_window_state state; size_t b_off, c_off, temp; int line; os_coord os_line_height; rufl_code code; os_error *error; ta = (struct text_area *)self; if (!ta || ta->magic != MAGIC) { LOG(("magic doesn't match")); return; } if (ta->flags & TEXTAREA_READONLY) return; os_line_height.x = 0; os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1; ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1); state.w = ta->window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); return; } x = x - (state.visible.x0 - state.xscroll) - MARGIN_LEFT; y = (state.visible.y1 - state.yscroll) - y; line = y / ta->line_height; if (line < 0) line = 0; if (ta->line_count - 1 < (unsigned)line) line = ta->line_count - 1; code = rufl_x_to_offset(ta->font_family, ta->font_style, ta->font_size, ta->text + ta->lines[line].b_start, ta->lines[line].b_length, x, &b_off, &x); if (code != rufl_OK) { if (code == rufl_FONT_MANAGER_ERROR) LOG(("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess)); else LOG(("rufl_x_to_offset: 0x%x", code)); return; } for (temp = 0, c_off = 0; temp < b_off + ta->lines[line].b_start; temp = utf8_next(ta->text, ta->text_len, temp)) c_off++; ro_textarea_set_caret((uintptr_t)ta, c_off); }
/** * Update the a text area following a change in the parent icon * * \param self Text area to update */ bool ro_textarea_update(uintptr_t self) { struct text_area *ta; wimp_window_state state; wimp_icon_state istate; os_box extent; os_error *error; ta = (struct text_area *)self; if (!ta || ta->magic != MAGIC) return false; state.w = ta->parent; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); return false; } istate.w = ta->parent; istate.i = ta->icon; error = xwimp_get_icon_state(&istate); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); return false; } state.w = ta->window; state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - ro_get_vscroll_width(ta->window) - state.xscroll; state.visible.x0 += istate.icon.extent.x0 + 2 - state.xscroll; state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + ro_get_hscroll_height(ta->window) - state.yscroll; state.visible.y1 += istate.icon.extent.y1 - 2 - state.yscroll; if (ta->flags & TEXTAREA_READONLY) { state.visible.x0 += 2; state.visible.x1 -= 4; state.visible.y0 += 2; state.visible.y1 -= 4; } /* set our width/height */ ta->vis_width = state.visible.x1 - state.visible.x0; ta->vis_height = state.visible.y1 - state.visible.y0; /* Set window extent to visible area */ extent.x0 = 0; extent.y0 = -ta->vis_height; extent.x1 = ta->vis_width; extent.y1 = 0; error = xwimp_set_extent(ta->window, &extent); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); return false; } /* and open the window */ error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), ta->parent, wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_XORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT << wimp_CHILD_YORIGIN_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_LS_EDGE_SHIFT | wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_RS_EDGE_SHIFT); if (error) { LOG(("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess)); return false; } /* reflow the text */ ro_textarea_reflow(ta, 0); return true; }