diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libgfx/include/libgfx/draw.h | 24 | ||||
-rw-r--r-- | lib/libgfx/include/libgfx/gfx.h | 13 | ||||
-rw-r--r-- | lib/libgfx/src/draw.c | 74 | ||||
-rw-r--r-- | lib/liboda/include/liboda/input.h | 74 | ||||
-rw-r--r-- | lib/liboda/include/liboda/oda.h | 18 | ||||
-rw-r--r-- | lib/liboda/src/input.c | 88 | ||||
-rw-r--r-- | lib/liboda/src/window.c | 108 |
7 files changed, 379 insertions, 20 deletions
diff --git a/lib/libgfx/include/libgfx/draw.h b/lib/libgfx/include/libgfx/draw.h index 60d2b24..9f56f6c 100644 --- a/lib/libgfx/include/libgfx/draw.h +++ b/lib/libgfx/include/libgfx/draw.h @@ -36,6 +36,17 @@ /* Shape types */ #define SHAPE_SQUARE 0x00000000 +/* Basic color defines */ +#define GFX_BLACK 0x000000 +#define GFX_RED 0xFF0000 +#define GFX_GREEN 0x00FF00 +#define GFX_BLUE 0x0000FF +#define GFX_WHITE 0xFFFFFF +#define GFX_PURPLE 0x800080 +#define GFX_YELLOW 0xFFFF00 +#define GFX_DARK 0x1D2021 +#define GFX_AQUA 0x427B58 + /* * Default shape initializer, something that * works and can be tweaked. The idea of this @@ -78,7 +89,20 @@ struct gfx_shape { dimm_t height; }; +/* + * A point or single pixel that + * may be plotted onto the screen. + * + * @x,y: Position of the point on the screen + * @rgb: Color of the point (RGB) + */ +struct gfx_point { + scrpos_t x, y; + color_t rgb; +}; + int gfx_draw_shape(struct gfx_ctx *ctx, const struct gfx_shape *shape); +int gfx_plot_point(struct gfx_ctx *ctx, const struct gfx_point *point); __always_inline static inline size_t gfx_io_index(struct gfx_ctx *ctx, scrpos_t x, scrpos_t y) diff --git a/lib/libgfx/include/libgfx/gfx.h b/lib/libgfx/include/libgfx/gfx.h index 8ff48b4..67a1006 100644 --- a/lib/libgfx/include/libgfx/gfx.h +++ b/lib/libgfx/include/libgfx/gfx.h @@ -48,19 +48,6 @@ typedef uint32_t pixel_t; typedef pixel_t color_t; /* - * Basic color defines - */ -#define GFX_BLACK 0x000000 -#define GFX_RED 0xFF0000 -#define GFX_GREEN 0x00FF00 -#define GFX_BLUE 0x0000FF -#define GFX_WHITE 0xFFFFFF -#define GFX_PURPLE 0x800080 -#define GFX_YELLOW 0xFFFF00 -#define GFX_DARK 0x1D2021 -#define GFX_AQUA 0x427B58 - -/* * Represents cartesian x/y values */ typedef uint32_t cartpos_t; diff --git a/lib/libgfx/src/draw.c b/lib/libgfx/src/draw.c index 49f2f53..9ef8630 100644 --- a/lib/libgfx/src/draw.c +++ b/lib/libgfx/src/draw.c @@ -33,6 +33,39 @@ #include <libgfx/draw.h> /* + * See if a pixel is within the bounds of + * the screen. + * + * @ctx: Graphics context pointer + * @x: X position to check + * @y: Y position to check + * + * Returns 0 if within bounds, otherwise + * a negative value. + */ +static int +gfx_pixel_bounds(struct gfx_ctx *ctx, uint32_t x, uint32_t y) +{ + scrpos_t scr_width, scr_height; + struct fbattr fbdev; + + if (ctx == NULL) { + return -1; + } + + /* Grab screen dimensions */ + fbdev = ctx->fbdev; + scr_width = fbdev.width; + scr_height = fbdev.height; + + if (x >= scr_height || y >= scr_width) { + return -1; + } + + return 0; +} + +/* * Draw a classic square onto the screen. * * @ctx: Graphics context @@ -43,21 +76,15 @@ gfx_draw_square(struct gfx_ctx *ctx, const struct gfx_shape *shape) { struct fbattr fbdev; off_t idx; - scrpos_t scr_width, scr_height; scrpos_t x, y; if (ctx == NULL || shape == NULL) { return -EINVAL; } - /* Grab screen dimensions */ - fbdev = ctx->fbdev; - scr_width = fbdev.width; - scr_height = fbdev.height; - for (x = shape->x; x < shape->x + shape->width; ++x) { for (y = shape->y; y < shape->y + shape->height; ++y) { - if (x >= scr_width || y >= scr_height) { + if (gfx_pixel_bounds(ctx, x, y) < 0) { break; } @@ -69,6 +96,39 @@ gfx_draw_square(struct gfx_ctx *ctx, const struct gfx_shape *shape) } /* + * Plot a single pixel (aka point) onto + * the screen. + * + * @ctx: The graphics context pointer + * @point: Point to plot + * + * Returns 0 on success, otherwise a less + * than zero value. + */ +int +gfx_plot_point(struct gfx_ctx *ctx, const struct gfx_point *point) +{ + uint32_t index; + + if (ctx == NULL || point == NULL) { + return -EINVAL; + } + + /* + * Is this even a valid point on the screen for + * us to plot on? + */ + if (gfx_pixel_bounds(ctx, point->x, point->y) < 0) { + return -1; + } + + /* Plot it !! */ + index = gfx_io_index(ctx, point->x, point->y); + ctx->io[index] = point->rgb; + return 0; +} + +/* * Draw a shape onto the screen * * @ctx: libgfx graphics context diff --git a/lib/liboda/include/liboda/input.h b/lib/liboda/include/liboda/input.h new file mode 100644 index 0000000..c74a304 --- /dev/null +++ b/lib/liboda/include/liboda/input.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBODA_INPUT_H +#define LIBODA_INPUT_H + +#include <stdint.h> +#include <stddef.h> + +/* + * Macros to help extract scancode and + * character + */ +#define ODA_SCANCODE(KEY) ((KEY) >> 8) +#define ODA_KEYCHAR(KEY) ((char )(KEY) & 0xFF) + +/* + * Key defines + */ +#define ODA_KEY_OTHER 0x0000 +#define ODA_KEY_ESCAPE 0x0001 +#define ODA_KEY_TAB 0x0002 +#define ODA_KEY_BACKSPACE 0x0003 + +/* + * Represents a key press + * + * @type: Key types (see ODA_KEY_*) + * @scancode: Scancode + * @ch: Character + */ +struct oda_key { + uint16_t type; + uint8_t scancode; + char ch; +}; + +/* + * ODA keyboard object for managing keyboard + * input. + */ +struct oda_kbd { + int(*handle_keyev)(struct oda_kbd *kbd, struct oda_key *key); +}; + +int oda_kbd_dispatch(struct oda_kbd *kbd); + +#endif /* !LIBODA_INPUT_H */ 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/input.c b/lib/liboda/src/input.c new file mode 100644 index 0000000..797a9d4 --- /dev/null +++ b/lib/liboda/src/input.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/ascii.h> +#include <sys/errno.h> +#include <sys/param.h> +#include <liboda/oda.h> +#include <liboda/input.h> +#include <stdint.h> +#include <stdio.h> + +/* + * Convert key scancode/char values to fixed + * ODA key constants + */ +static inline uint16_t +oda_map_key(const struct oda_key *key) +{ + uint16_t type = ODA_KEY_OTHER; + + switch (key->ch) { + case ASCII_ESC: + type = ODA_KEY_ESCAPE; + break; + case ASCII_HT: + type = ODA_KEY_TAB; + break; + case ASCII_BS: + type = ODA_KEY_BACKSPACE; + break; + } + + return type; +} + +/* + * Dispatch keyboard events. This is typically + * called in an event loop so that keyboard events + * are handled per iteration. + * + * @kbd: Keyboard to monitor + */ +int +oda_kbd_dispatch(struct oda_kbd *kbd) +{ + struct oda_key key; + int input; + + if (kbd == NULL) { + return -EINVAL; + } + + /* Attempt to grab the input */ + if ((input = getchar()) < 0) { + return -EAGAIN; + } + + key.scancode = ODA_SCANCODE(input); + key.ch = ODA_KEYCHAR(input); + key.type = oda_map_key(&key); + return kbd->handle_keyev(kbd, &key); +} 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 @@ -36,6 +36,114 @@ #include <libgfx/gfx.h> /* + * 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). * |