From 5521347322892f4997644925acfe1edf2c6b0bbf Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 3 Aug 2025 03:44:09 -0400 Subject: lib: liboda: Add oda_plotwin() window plotter Introduce the oda_plotwin() function to allow one to plot a pixel onto a window relative to the starting X/Y position of it. Plotting to (0,0) draws to the top left corner of the window. Signed-off-by: Ian Moffett --- lib/liboda/include/liboda/oda.h | 18 +++++++ lib/liboda/src/window.c | 108 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) (limited to 'lib') diff --git a/lib/liboda/include/liboda/oda.h b/lib/liboda/include/liboda/oda.h index d807a50..10738a9 100644 --- a/lib/liboda/include/liboda/oda.h +++ b/lib/liboda/include/liboda/oda.h @@ -80,8 +80,26 @@ struct oda_wattr { odadimm_t w, h; }; +/* + * A pixel point that can be plotted + * onto a window. + * + * @x,y: Point position + * @rgb: Color (RGB) + * @window: Window this will be plotted to + * + * Just set x, y, the color (rgb) then point it + * to a window! + */ +struct oda_point { + odapos_t x, y; + odacolor_t rgb; + struct oda_window *window; +}; + int oda_reqwin(struct oda_wattr *params, struct oda_window **res); int oda_termwin(struct oda_state *state, struct oda_window *win); +int oda_plotwin(struct oda_state *state, const struct oda_point *point); int oda_start_win(struct oda_state *state, struct oda_window *win); int oda_init(struct oda_state *res); diff --git a/lib/liboda/src/window.c b/lib/liboda/src/window.c index 876f89e..9a8b799 100644 --- a/lib/liboda/src/window.c +++ b/lib/liboda/src/window.c @@ -35,6 +35,114 @@ #include #include +/* + * Check if a point is within the bounds of + * a surface. + * + * @wp: Surface to check with point + * @point: Point to check with surface + * + * Returns 0 if the check has passed, + * otherwise a less than zero value. + */ +static int +oda_check_point(struct oda_window *wp, struct oda_point *point) +{ + struct gfx_shape *surf; + scrpos_t win_startx; + scrpos_t win_starty; + scrpos_t win_endx; + scrpos_t win_endy; + + /* Compute start positions */ + surf = &wp->surface; + win_startx = surf->x; + win_starty = surf->y; + + /* Compute end positions */ + win_endx = surf->x + surf->width; + win_endy = surf->y + surf->height; + + /* Check X bounds */ + if (point->x < win_startx || point->x > win_endx) { + return -1; + } + + /* Check Y bounds */ + if (point->y < win_starty || point->y > win_endy) { + return -1; + } + + /* All good */ + return 0; +} + +/* + * Plot a pixel onto a window + * + * @state: ODA state pointer + * @point: Point to plot + * + * Returns 0 on success, otherwise a less than + * zero value. + * + * XXX: The x/y params in the 'point' argument must be + * relative to the start of the window. In other words, + * (0,0) refers to the top left corner of the window. + */ +int +oda_plotwin(struct oda_state *state, const struct oda_point *point) +{ + struct gfx_point pixel; + struct oda_point point_new; + struct oda_window *window; + struct gfx_shape *surf; + odapos_t plotx, ploty; + int error; + + if (state == NULL || point == NULL) { + return -EINVAL; + } + + /* Validate cookie */ + if ((error = oda_cookie_verify(state)) != 0) { + return error; + } + + /* Try to grab the window */ + if ((window = point->window) == NULL) { + return -EINVAL; + } + + surf = &window->surface; + plotx = surf->x + point->x; + ploty = surf->y + point->y; + + /* + * We are going to need to transform the coordinates + * as they are supposed to be coming in relative to + * the window bounds, e.g., (0,0) being the top left + * corner of a window. + */ + point_new = *point; + point_new.x = plotx; + point_new.y = ploty; + + /* Initialize the pixel to plot */ + pixel.x = plotx; + pixel.y = ploty; + pixel.rgb = point->rgb; + + /* Is the point within bounds? */ + error = oda_check_point(window, &point_new); + if (error < 0) { + return error; + } + + gfx_plot_point(&state->gctx, &pixel); + return 0; +} + /* * Request a window from the OSMORA Display * Architecture (ODA). -- cgit v1.2.3