示例#1
0
文件: treeview.c 项目: ysei/NetSurf
void ro_treeview_pointer_entering(wimp_entering *entering)
{
	ro_treeview		*tv;

	tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(entering->w);
	if (tv == NULL)
		return;

	ro_mouse_track_start(NULL, ro_treeview_mouse_at, NULL);
} 
示例#2
0
/**
 * Handle acceptance of query dialog
 */
bool ro_gui_query_apply(wimp_w w)
{
	struct gui_query_window *qw;
	const query_callback *cb;

	qw = (struct gui_query_window *)ro_gui_wimp_event_get_user_data(w);
	cb = qw->cb;
	cb->confirm(qw->id, QUERY_YES, qw->pw);
	return true;
}
示例#3
0
void ro_gui_cert_reject(wimp_pointer *pointer)
{
	struct ro_sslcert *s;

	s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w);

	if (s != NULL) {
		sslcert_reject(s->data);
		ro_gui_dialog_close(s->window);
		ro_gui_cert_release_window(s);
	}
}
示例#4
0
/**
 * Handle clicks in query dialog
 */
bool ro_gui_query_click(wimp_pointer *pointer)
{
	struct gui_query_window *qw;
	const query_callback *cb;

	qw = (struct gui_query_window *)ro_gui_wimp_event_get_user_data(pointer->w);
	cb = qw->cb;

	switch (pointer->i) {
		case ICON_QUERY_NO:
			cb->cancel(qw->id, QUERY_NO, qw->pw);
			break;
		default:
			return false;
	}
	return false;
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
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);
}
示例#8
0
static bool ro_treeview_keypress(wimp_key *key)
{
	ro_treeview		*tv;
	uint32_t		c;

	tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(key->w);
	if (tv == NULL) {
		LOG(("NULL treeview block for window: 0x%x",
				(unsigned int) key->w));
		return false;
	}

	c = (uint32_t) key->c;

	if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
			(c & IS_WIMP_KEY)) {
	/* Munge control keys into unused control chars */
	/* We can't map onto 1->26 (reserved for ctrl+<qwerty>
	   That leaves 27->31 and 128->159 */
		switch (c & ~IS_WIMP_KEY) {
		case wimp_KEY_TAB: c = 9; break;
		case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;

		/* cursor movement keys */
		case wimp_KEY_HOME:
		case wimp_KEY_CONTROL | wimp_KEY_LEFT:
			c = KEY_LINE_START;
			break;
		case wimp_KEY_END:
			if (os_version >= RISCOS5)
				c = KEY_LINE_END;
			else
				c = KEY_DELETE_RIGHT;
			break;
		case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END;   break;
		case wimp_KEY_CONTROL | wimp_KEY_UP:	c = KEY_TEXT_START; break;
		case wimp_KEY_CONTROL | wimp_KEY_DOWN:  c = KEY_TEXT_END;   break;
		case wimp_KEY_SHIFT | wimp_KEY_LEFT:	c = KEY_WORD_LEFT ; break;
		case wimp_KEY_SHIFT | wimp_KEY_RIGHT:	c = KEY_WORD_RIGHT; break;
		case wimp_KEY_SHIFT | wimp_KEY_UP:	c = KEY_PAGE_UP;    break;
		case wimp_KEY_SHIFT | wimp_KEY_DOWN:	c = KEY_PAGE_DOWN;  break;
		case wimp_KEY_LEFT:  c = KEY_LEFT; break;
		case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
		case wimp_KEY_UP:    c = KEY_UP; break;
		case wimp_KEY_DOWN:  c = KEY_DOWN; break;

		/* editing */
		case wimp_KEY_CONTROL | wimp_KEY_END:
			c = KEY_DELETE_LINE_END;
			break;
		case wimp_KEY_DELETE:
			if (ro_gui_ctrl_pressed())
				c = KEY_DELETE_LINE_START;
			else if (os_version < RISCOS5)
				c = KEY_DELETE_LEFT;
			break;

		default:
			break;
		}
	}

	if (!(c & IS_WIMP_KEY)) {
		if (tree_keypress(tv->tree, c)) {
			if (tv->callbacks &&
					tv->callbacks->toolbar_button_update
					!= NULL)
				tv->callbacks->toolbar_button_update();

			return true;
		}
	}

	return false;
}
示例#9
0
/**
 * Handle key presses in a text area
 *
 * \param key Key pressed state block
 * \param true if press handled, false otherwise
 */
bool ro_textarea_key_press(wimp_key *key)
{
	uint32_t c = (uint32_t) key->c;
	wimp_key keypress;
	struct text_area *ta;
	char utf8[7];
	size_t utf8_len;
	bool redraw = false;
	unsigned int c_pos;
	os_error *error;

	ta = (struct text_area *)ro_gui_wimp_event_get_user_data(key->w);

	if (ta->flags & TEXTAREA_READONLY)
		return true;

	if (!(c & IS_WIMP_KEY ||
			(c <= 0x001f || (0x007f <= c && c <= 0x009f)))) {
		/* normal character - insert */
		utf8_len = utf8_from_ucs4(c, utf8);
		utf8[utf8_len] = '\0';

		c_pos = ro_textarea_get_caret((uintptr_t)ta);
		ro_textarea_insert_text((uintptr_t)ta, c_pos, utf8);
		ro_textarea_set_caret((uintptr_t)ta, ++c_pos);

		redraw = true;
	} else {
		/** \todo handle command keys */
		switch (c & ~IS_WIMP_KEY) {
		case 8: /* Backspace */
			c_pos = ro_textarea_get_caret((uintptr_t)ta);
			if (c_pos > 0) {
				ro_textarea_replace_text((uintptr_t)ta,
					c_pos - 1, c_pos, "");
				ro_textarea_set_caret((uintptr_t)ta, c_pos - 1);
				redraw = true;
			}
			break;
		case 21: /* Ctrl + U */
			ro_textarea_set_text((uintptr_t)ta, "");
			ro_textarea_set_caret((uintptr_t)ta, 0);
			redraw = true;
			break;
		case wimp_KEY_DELETE:
			c_pos = ro_textarea_get_caret((uintptr_t)ta);
			if (os_version < RISCOS5 && c_pos > 0) {
				ro_textarea_replace_text((uintptr_t)ta,
						c_pos - 1, c_pos, "");
				ro_textarea_set_caret((uintptr_t)ta, c_pos - 1);
			} else {
				ro_textarea_replace_text((uintptr_t)ta, c_pos,
						c_pos + 1, "");
			}
			redraw = true;
			break;

		case wimp_KEY_LEFT:
			c_pos = ro_textarea_get_caret((uintptr_t)ta);
			if (c_pos > 0)
				ro_textarea_set_caret((uintptr_t)ta, c_pos - 1);
			break;
		case wimp_KEY_RIGHT:
			c_pos = ro_textarea_get_caret((uintptr_t)ta);
			ro_textarea_set_caret((uintptr_t)ta, c_pos + 1);
			break;
		case wimp_KEY_UP:
			/** \todo Move caret up a line */
			break;
		case wimp_KEY_DOWN:
			/** \todo Move caret down a line */
			break;

		case wimp_KEY_HOME:
		case wimp_KEY_CONTROL | wimp_KEY_LEFT:
			/** \todo line start */
			break;
		case wimp_KEY_CONTROL | wimp_KEY_RIGHT:
			/** \todo line end */
			break;
		case wimp_KEY_CONTROL | wimp_KEY_UP:
			ro_textarea_set_caret((uintptr_t)ta, 0);
			break;
		case wimp_KEY_CONTROL | wimp_KEY_DOWN:
			ro_textarea_set_caret((uintptr_t)ta,
					utf8_length(ta->text));
			break;

		case wimp_KEY_COPY:
			if (os_version < RISCOS5) {
				c_pos = ro_textarea_get_caret((uintptr_t)ta);
				ro_textarea_replace_text((uintptr_t)ta, c_pos,
						c_pos + 1, "");
			} else {
				/** \todo line end */
			}
			break;

		/** pass on RETURN and ESCAPE to the parent icon */
		case wimp_KEY_RETURN:
			if (ta->flags & TEXTAREA_MULTILINE) {
				/* Insert newline */
				c_pos = ro_textarea_get_caret((uintptr_t)ta);
				ro_textarea_insert_text((uintptr_t)ta, c_pos,
						"\n");
				ro_textarea_set_caret((uintptr_t)ta, ++c_pos);

				redraw = true;

				break;
			}
			/* fall through */
		case wimp_KEY_ESCAPE:
			keypress = *key;
			keypress.w = ta->parent;
			keypress.i = ta->icon;
			keypress.index = 0; /* undefined if not in an icon */
			error = xwimp_send_message_to_window(wimp_KEY_PRESSED,
					(wimp_message*)&keypress, ta->parent,
					ta->icon, 0);
			if (error) {
				LOG(("xwimp_send_message: 0x%x:%s",
					error->errnum, error->errmess));
			}
			break;
		}
	}

	if (redraw) {
		wimp_draw update;

		update.w = ta->window;
		update.box.x0 = 0;
		update.box.y1 = 0;
		update.box.x1 = ta->vis_width;
		update.box.y0 = -ta->line_height * (ta->line_count + 1);
		ro_textarea_redraw_internal(&update, true);
	}

	return true;
}
示例#10
0
/**
 * Internal textarea redraw routine
 *
 * \param redraw Redraw/update request block
 * \param update True if update, false if full redraw
 */
void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
{
	struct text_area *ta;
	int clip_x0, clip_y0, clip_x1, clip_y1;
	int line0, line1, line;
	osbool more;
	rufl_code code;
	os_error *error;

	ta = (struct text_area *)ro_gui_wimp_event_get_user_data(redraw->w);

	if (update)
		error = xwimp_update_window(redraw, &more);
	else
		error = xwimp_redraw_window(redraw, &more);
	if (error) {
		LOG(("xwimp_redraw_window: 0x%x: %s",
				error->errnum, error->errmess));
		return;
	}

	while (more) {
		clip_x0 = redraw->clip.x0 - (redraw->box.x0-redraw->xscroll);
		clip_y0 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y1;
		clip_x1 = redraw->clip.x1 - (redraw->box.x0-redraw->xscroll);
		clip_y1 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y0;

		error = xcolourtrans_set_gcol(
				(ta->flags & TEXTAREA_READONLY) ? 0xD9D9D900
								: 0xFFFFFF00,
				colourtrans_SET_BG_GCOL | colourtrans_USE_ECFS_GCOL,
				os_ACTION_OVERWRITE, 0, 0);
		if (error) {
			LOG(("xcolourtrans_set_gcol: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}

		error = xos_clg();
		if (error) {
			LOG(("xos_clg: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}

		if (!ta->lines)
			/* Nothing to redraw */
			return;

		line0 = clip_y0 / ta->line_height - 1;
		line1 = clip_y1 / ta->line_height + 1;

		if (line0 < 0)
			line0 = 0;
		if (line1 < 0)
			line1 = 0;
		if (ta->line_count - 1 < (unsigned)line0)
			line0 = ta->line_count - 1;
		if (ta->line_count - 1 < (unsigned)line1)
			line1 = ta->line_count - 1;
		if (line1 < line0)
			line1 = line0;

		for (line = line0; line <= line1; line++) {
			if (ta->lines[line].b_length == 0)
				continue;

			error = xcolourtrans_set_font_colours(font_CURRENT,
					(ta->flags & TEXTAREA_READONLY) ?
						0xD9D9D900 : 0xFFFFFF00,
					0x00000000, 14, 0, 0, 0);
			if (error) {
				LOG(("xcolourtrans_set_font_colours: 0x%x: %s",
					error->errnum, error->errmess));
				return;
			}

			code = rufl_paint(ta->font_family, ta->font_style,
					ta->font_size,
					ta->text + ta->lines[line].b_start,
					ta->lines[line].b_length,
					redraw->box.x0 - redraw->xscroll + MARGIN_LEFT,
					redraw->box.y1 - redraw->yscroll -
						((line + 1) *
						ta->line_height - ta->line_spacing),
					rufl_BLEND_FONT);
			if (code != rufl_OK) {
				if (code == rufl_FONT_MANAGER_ERROR)
					LOG(("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
						rufl_fm_error->errnum,
						rufl_fm_error->errmess));
				else
					LOG(("rufl_paint: 0x%x", code));
			}
		}

		error = xwimp_get_rectangle(redraw, &more);
		if (error) {
			LOG(("xwimp_get_rectangle: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}
	}
}