diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/libgfx/Makefile | 1 | ||||
-rw-r--r-- | lib/libgfx/include/libgfx/draw.h | 24 | ||||
-rw-r--r-- | lib/libgfx/include/libgfx/gfx.h | 11 | ||||
-rw-r--r-- | lib/libgfx/src/draw.c | 74 | ||||
-rw-r--r-- | lib/liboda/Makefile | 29 | ||||
-rw-r--r-- | lib/liboda/include/liboda/input.h | 74 | ||||
-rw-r--r-- | lib/liboda/include/liboda/oda.h | 107 | ||||
-rw-r--r-- | lib/liboda/include/liboda/odavar.h | 59 | ||||
-rw-r--r-- | lib/liboda/include/liboda/types.h | 40 | ||||
-rw-r--r-- | lib/liboda/src/input.c | 88 | ||||
-rw-r--r-- | lib/liboda/src/oda.c | 77 | ||||
-rw-r--r-- | lib/liboda/src/window.c | 261 |
13 files changed, 827 insertions, 19 deletions
diff --git a/lib/Makefile b/lib/Makefile index 4ad104b..fc77815 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -7,3 +7,4 @@ ARGS = -I$(ROOT)/builddeps LDSCRIPT=$(LDSCRIPT) USRDIR=$(USRDIR) ROOT=$(ROOT) all: make -C libc/ $(ARGS) make -C libgfx/ $(ARGS) + make -C liboda/ $(ARGS) diff --git a/lib/libgfx/Makefile b/lib/libgfx/Makefile index 1f866ac..12fdd9a 100644 --- a/lib/libgfx/Makefile +++ b/lib/libgfx/Makefile @@ -4,7 +4,6 @@ CFILES = $(shell find src/ -name "*.c") OBJ = $(CFILES:.c=.o) all: headers $(OBJ) build/libgfx.a - echo "----------------------------------------" echo $(USRDIR) mv build/libgfx.a $(USRDIR)/lib/ cp -r include/ $(USRDIR)/include/ 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 3468571..67a1006 100644 --- a/lib/libgfx/include/libgfx/gfx.h +++ b/lib/libgfx/include/libgfx/gfx.h @@ -48,17 +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 - -/* * 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/Makefile b/lib/liboda/Makefile new file mode 100644 index 0000000..5b4022c --- /dev/null +++ b/lib/liboda/Makefile @@ -0,0 +1,29 @@ +CFLAGS = -c -fno-stack-protector -nostdlib -static \ + -Iinclude/ -I$(USRDIR)/include/ +CFILES = $(shell find src/ -name "*.c") +OBJ = $(CFILES:.c=.o) + +all: headers $(OBJ) build/liboda.a + echo $(USRDIR) + mv build/liboda.a $(USRDIR)/lib/ + cp -r include/ $(USRDIR)/include/ + +build/liboda.a: + mkdir -p build/ + ar rcs build/liboda.a $(OBJ) + +%.o: %.c + $(CC) $(CFLAGS) -Iinclude/ $< -o $@ + +.PHONY: headers +headers: + cp -rf include/* $(USRDIR)/include/ + +.PHONY: +build/: + mkdir -p build/ + +.PHONY: clean +clean: + rm -f $(OBJ) + rm -rf build/ 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 new file mode 100644 index 0000000..10738a9 --- /dev/null +++ b/lib/liboda/include/liboda/oda.h @@ -0,0 +1,107 @@ +/* + * 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_ODA_H +#define LIBODA_ODA_H 1 + +#include <sys/queue.h> +#include <stdint.h> +#include <stddef.h> +#include <liboda/types.h> +#include <libgfx/gfx.h> +#include <libgfx/draw.h> + +/* + * ODA representation of a window. + * + * @surface: Window surface descriptor + * @session: Session this window belongs to + */ +struct oda_window { + struct gfx_shape surface; + struct oda_state *session; + TAILQ_ENTRY(oda_window) link; +}; + +/* + * ODA session + * + * @winq: Window queue + * @gctx: Graphics context + * @cookie: State cookie (ODA_COOKIE) + */ +struct oda_state { + TAILQ_HEAD(, oda_window) winq; + struct gfx_ctx gctx; + uint32_t cookie; +}; + +/* + * ODA window attributes. Arguments to be + * passed to oda_window_new() + * + * @session: Current ODA session / state + * @parent: Window parent (NULL for root) + * @pg: Background color (0xRRGGBB) + * @x,y: Window position + * @w,h: Window width [w] and height [h] + */ +struct oda_wattr { + struct oda_state *session; + struct oda_window *parent; + odacolor_t bg; + odapos_t x, y; + 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); + +#endif /* !LIBODA_ODA_H */ diff --git a/lib/liboda/include/liboda/odavar.h b/lib/liboda/include/liboda/odavar.h new file mode 100644 index 0000000..d2dbe2e --- /dev/null +++ b/lib/liboda/include/liboda/odavar.h @@ -0,0 +1,59 @@ +/* + * 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_ODAVAR_H +#define LIBODA_ODAVAR_H + +#include <sys/param.h> +#include <sys/errno.h> +#include <liboda/oda.h> + +/* + * Default window attributes + */ +#define DEFAULT_WIN_HEIGHT 200 +#define DEFAULT_WIN_WIDTH 150 + +/* + * Verify that ODA structures have been properly + * initialized before usage to prevent undefined + * behaviour. + */ +#define ODA_COOKIE 0xFAFECAD + +/* + * Verify an ODA cookie - internal usage + */ +__always_inline static inline int +oda_cookie_verify(struct oda_state *state) +{ + return (state->cookie == ODA_COOKIE) ? 0 : -EFAULT; +} + +#endif /* !LIBODA_ODAVAR_H */ diff --git a/lib/liboda/include/liboda/types.h b/lib/liboda/include/liboda/types.h new file mode 100644 index 0000000..8b77aa7 --- /dev/null +++ b/lib/liboda/include/liboda/types.h @@ -0,0 +1,40 @@ +/* + * 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_TYPE_H +#define LIBODA_TYPE_H + +#include <stdint.h> + +typedef uint32_t odapos_t; /* X/Y positions */ +typedef uint32_t odapix_t; /* RGB pixel */ +typedef odapix_t odacolor_t; /* RGB color */ +typedef uint32_t odadimm_t; /* Dimensions */ + +#endif /* !LIBODA_TYPE_H */ 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/oda.c b/lib/liboda/src/oda.c new file mode 100644 index 0000000..0eef523 --- /dev/null +++ b/lib/liboda/src/oda.c @@ -0,0 +1,77 @@ +/* + * 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/errno.h> +#include <stdio.h> +#include <libgfx/gfx.h> +#include <liboda/oda.h> +#include <liboda/odavar.h> + +#define oda_log(fmt, ...) printf("oda: " fmt, ##__VA_ARGS__) + +/* + * Initialize the OSMORA Display Architecture + * (ODA) library. + * + * @res: Initialized ODA state result + * + * Returns 0 on success, otherwise a less than + * zero value. + */ +int +oda_init(struct oda_state *res) +{ + int error; + + /* Ensure the argument is valid */ + if (res == NULL) { + return -EINVAL; + } + + /* + * If this state has already been initialized, + * assume programmer error / undefined behaviour + * and let them know. + */ + if (oda_cookie_verify(res) == 0) { + oda_log("oda_init: 'res' already initialized\n"); + return -EBUSY; + } + + /* Initialize the graphics context */ + error = gfx_init(&res->gctx); + if (error != 0) { + oda_log("oda_init: could not init graphics context\n"); + return error; + } + + TAILQ_INIT(&res->winq); + res->cookie = ODA_COOKIE; + return 0; +} diff --git a/lib/liboda/src/window.c b/lib/liboda/src/window.c new file mode 100644 index 0000000..9a8b799 --- /dev/null +++ b/lib/liboda/src/window.c @@ -0,0 +1,261 @@ +/* + * 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/errno.h> +#include <stdlib.h> +#include <string.h> +#include <liboda/oda.h> +#include <liboda/odavar.h> +#include <liboda/types.h> +#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). + * + * @params: Arguments + * @res: Resulting pointer for new window + * + * Returns 0 on success, otherwise a less than + * zero value. + */ +int +oda_reqwin(struct oda_wattr *params, struct oda_window **res) +{ + struct oda_window *wp; + struct gfx_shape *surf; + struct oda_state *session; + int error; + + if (params == NULL || res == NULL) { + return -EINVAL; + } + + /* Try to grab the current session */ + if ((session = params->session) == NULL) { + return -EIO; + } + + /* Verify that cookie! */ + if ((error = oda_cookie_verify(session)) != 0) { + return error; + } + + /* Allocate a new window */ + wp = malloc(sizeof(*wp)); + if (wp == NULL) { + return -ENOMEM; + } + + /* Initialize the window */ + memset(wp, 0, sizeof(*wp)); + wp->session = session; + TAILQ_INSERT_TAIL(&session->winq, wp, link); + + /* Fix up width/height params */ + if (params->w == 0) + params->w = DEFAULT_WIN_WIDTH; + if (params->h == 0) + params->h = DEFAULT_WIN_HEIGHT; + + /* Initialize the window surface */ + surf = &wp->surface; + surf->color = params->bg; + surf->x = params->x; + surf->y = params->y; + surf->width = params->w; + surf->height = params->h; + surf->type = SHAPE_SQUARE; + *res = wp; + return 0; +} + +/* + * Register a window into the current ODA state. + * Everytime a compositor requests a window, we + * must keep track of it. + * + * @state: ODA state pointer + * @win: Pointer of window to register + */ +int +oda_start_win(struct oda_state *state, struct oda_window *win) +{ + int error; + + if (state == NULL || win == NULL) { + return -EINVAL; + } + + /* Make sure the state is valid */ + if ((error = oda_cookie_verify(state)) != 0) { + return error; + } + + gfx_draw_shape(&state->gctx, &win->surface); + return 0; +} + +/* + * Terminate a running window + * + * @state: ODA state pointer + * @win: Win pointer + * + * Returns 0 on success, otherwise a less than + * zero value. + * + * TODO: Cleanup screen + */ +int +oda_termwin(struct oda_state *state, struct oda_window *win) +{ + int error; + + if (state == NULL || win == NULL) { + return -EINVAL; + } + + /* Validate the cookie */ + if ((error = oda_cookie_verify(state)) != 0) { + return error; + } + + TAILQ_REMOVE(&state->winq, win, link); + free(win); + return 0; +} |