Esempio n. 1
0
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);
}
Esempio n. 2
0
void ro_gui_debugwin_resize(void)
{
	int width, height;
	os_box box;
	os_error *error;

	/* Ask the core for the debug window size */
	debugwin_get_size(&width, &height);

	box.x0 = 0;
	box.y0 = height * -2;
	box.x1 = width * 2;
	box.y1 = 0;
	error = xwimp_set_extent(dialog_debug, &box);
	if (error) {
		LOG(("xwimp_set_extent: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
/**
 * 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);
	}
}
Esempio n. 8
0
/**
 * 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;
}
Esempio n. 9
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;
	}
}
Esempio n. 10
0
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;
	}
}