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 Pointer Entering Window events the history window. * * \param *entering The Wimp_PointerEnteringWindow block. */ void ro_gui_history_pointer_entering(wimp_entering *entering) { ro_mouse_track_start(ro_gui_history_track_end, ro_gui_history_mouse_at, NULL); }
void ro_gui_debugwin_redraw(wimp_draw *redraw) { osbool more; os_error *error; /* Select RISC OS plotters */ plot = ro_plotters; ro_plot_set_scale(1.0); 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) { int clip_x0, clip_y0, clip_x1, clip_y1; /* Sep plot origin */ ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; /* Set clip rectangle */ clip_x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */ clip_y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */ clip_x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */ clip_y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */ plot.clip(clip_x0, clip_y0, clip_x1, clip_y1); /* Render the content debug table */ debugwin_redraw(clip_x0, clip_y0, clip_x1, clip_y1); 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; } } }
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); }
/** * 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; } } }
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; } }
bool RiscosGui::run() { GNASH_REPORT_FUNCTION; os_t t, now; wimp_block block; wimp_event_no event; osbool more; os_error *error; t = os_read_monotonic_time(); while (!_quit) { error = xwimp_poll_idle(wimp_SAVE_FP, &block, t, NULL, &event); if (error) { log_debug("%s\n", error->errmess); return false; } switch (event) { case wimp_NULL_REASON_CODE: now = os_read_monotonic_time(); if (now > t) { if (_timeout > now) { _quit = true; } else { // TODO: pay attention to interval // if ((os_t)_interval <= (now - t) * 10) { advance_movie(this); // } now = os_read_monotonic_time(); t = now + 10; } } break; case wimp_REDRAW_WINDOW_REQUEST: error = xwimp_redraw_window(&block.redraw, &more); if (error) { log_debug("%s\n", error->errmess); return false; } while (more) { // rect bounds(block.redraw.clip.x0 / 2, block.redraw.clip.y0 / 2, // block.redraw.clip.x1 / 2, block.redraw.clip.y1 / 2); // log_debug("Clip rect: (%d, %d)(%d, %d)\n", // block.redraw.clip.x0 / 2, block.redraw.clip.y0 / 2, // block.redraw.clip.x1 / 2, block.redraw.clip.y1 / 2); // TODO: Make this use the clipping rectangle (convert to TWIPS) rect bounds(-1e10f, -1e10f, 1e10f, 1e10f); #ifdef RENDERER_AGG setInvalidatedRegion(bounds); #endif renderBuffer(); error = xwimp_get_rectangle(&block.redraw, &more); if (error) { log_debug("%s\n", error->errmess); return false; } } break; case wimp_OPEN_WINDOW_REQUEST: error = xwimp_open_window(&block.open); if (error) log_debug("%s\n", error->errmess); break; case wimp_CLOSE_WINDOW_REQUEST: _quit = true; break; case wimp_POINTER_LEAVING_WINDOW: break; case wimp_POINTER_ENTERING_WINDOW: break; case wimp_MOUSE_CLICK: break; case wimp_USER_DRAG_BOX: break; case wimp_MENU_SELECTION: break; case wimp_SCROLL_REQUEST: break; case wimp_LOSE_CARET: break; case wimp_GAIN_CARET: break; case wimp_POLLWORD_NON_ZERO: break; case wimp_USER_MESSAGE: case wimp_USER_MESSAGE_RECORDED: case wimp_USER_MESSAGE_ACKNOWLEDGE: switch (block.message.action) { case message_QUIT: _quit = true; break; default: // user_message(event, &(block.message)); break; } break; } } return true; }