diff options
Diffstat (limited to 'share/docs')
-rw-r--r-- | share/docs/kernel/ctlfs.md | 125 | ||||
-rw-r--r-- | share/docs/lib/liboda.md | 229 |
2 files changed, 354 insertions, 0 deletions
diff --git a/share/docs/kernel/ctlfs.md b/share/docs/kernel/ctlfs.md new file mode 100644 index 0000000..3087f60 --- /dev/null +++ b/share/docs/kernel/ctlfs.md @@ -0,0 +1,125 @@ +# The Hyra control filesystem (ctlfs) + +Written by Ian M. Moffett + +## Rationale + +Historically, Operating Systems of the Unix family typically relied +on syscalls like ``ioctl()`` or similar to perform operations (e.g., making calls through a driver) +via some file descriptor. Let's say for example, one wanted to acquire the framebuffer +dimensions of a given framebuffer device. To start, they'd acquire a file descriptor +by calling ``open()`` or similar on it. Then they'd make their ``ioctl()`` call. + +```c +int fd = ...; + +ioctl(fd, IOCTL_FBINFO, &fb_info); +... +``` + +While this works fine and is relatively simple to use from the user's +perspective, it is very clunky when you pop the hood and peer into the +inner-workings of it within the kernel. The number of possible requests +that can be passed through a file descriptor can grow quite rapidly which +can require really large switch statements within the drivers that implement +an ``ioctl()`` interface. + +## Replacing ``ioctl()`` + +Hyra provides ctlfs, an abstract in-memory filesystem designed for +setting/getting various kernel / driver parameters and state via +the filesystem API. The control filesystem consists of several +instances of two fundamentals: "control nodes" and "control entries". + +### Control nodes + +Control nodes are simply directories within the ``/ctl`` root. For example, +console specific control files are in the ``/ctl/console`` node. + +### Control entries + +Control entries are simply files within specific control nodes. For example +console features may be find in the ``consfeat`` entry of the ``console`` node +(i.e., ``/ctl/console/consfeat``). + +See ``sys/include/sys/console.h`` and ``sys/fs/ctlfs.h`` for more +information. + +## The ctlfs API + +The Hyra kernel provides an API for subsystems and drivers +to create their own ctlfs entries and nodes. This may be found +in sys/include/fs/ctlfs.h + +### Control operations + +Each control entry must define their own set of +"control operations" described by the ``ctlops`` structure: + +```c +struct ctlops { + int(*read)(struct ctlfs_dev *cdp, struct sio_txn *sio); + int(*write)(struct ctlfs_dev *cdp, struct sio_txn *sio); + ... +}; +``` + +NOTE: Callbacks defined as ``NULL`` will be +ignored and unused. + +## "Meow World": Creating a ctlfs entry + +```c +#include <sys/types.h> +#include <sys/sio.h> +#include <fs/ctlfs.h> + +static const struct ctlops meow_ctl; + +/* + * Ctlfs read callback - this will be called + * when "/ctl/meow/hii" is read. + */ +static int +ctl_meow_read(struct ctlfs_dev *cdp, struct sio_txn *sio) +{ + char data[] = "Meow World!"" + + /* Clamp the input length */ + if (sio->len > sizeof(data)) { + sio->len = sizeof(data) + } + + /* End of the data? */ + if ((sio->offset + sio->len) > sizeof(data)) { + return 0; + } + + /* Copy the data and return the length */ + memcpy(sio->buf, &data[sio->offset], sio->len); + return sio->len; +} + +static int +foo_init(void) +{ + char ctlname[] = "meow"; + struct ctlfs_dev ctl; + + /* + * Here we create the "/ctl/meow" node. + */ + ctl.mode = 0444; + ctl.devname = devname; + ctlfs_create_node(devname, &ctl); + + ctl.ops = &fb_size_ctl; + ctlfs_create_entry("attr", &ctl); + return 0; +} + +static const struct ctlops meow_ctl = { + .read = ctl_meow_read, + .write = NULL, +}; +``` diff --git a/share/docs/lib/liboda.md b/share/docs/lib/liboda.md new file mode 100644 index 0000000..e5345a4 --- /dev/null +++ b/share/docs/lib/liboda.md @@ -0,0 +1,229 @@ +# The OSMORA Display Architecture (ODA) + +Written by Ian M. Moffett + +## Introduction + +The OSMORA Display Architecture (ODA) is a protocol describing how +a compositor should create and manage graphical windows. A graphical +session in Hyra consists of a compositor, window management system and +management of user input. + +There are many existing display architectures out there. Take for instace, the X11 +protocol. X11 for example, has the concept of an "X server" in which window managers +or certain graphical programs would connect to as a means of performing interprocess +communication (IPC). The idea is that X will service graphics related requests from +the window manager or compositor. + +While this works just fine, the highly centralized nature of X11 or similar protocols +may complicate the flexibility of the graphics stack. On the other hand with ODA, a +compositor links with the ODA library and becomes the server for window managers running +on the system. The idea of ODA is to minimize complexity while preserving flexibility. + +Additionally, the compositor should provide its own API for use by window management +software. + +## Scope + +This document serves to describe common OSMORA Display Architecture (ODA) concepts +as well as providing basic example C sources showcasing how compositors and window +managers may interface with the described APIs for various needs. + +## Terminology + +### OSMORA Display Architecture (ODA): + +OSMORA protocol defining common interfaces for C2W and +W2C interactions. + +### Compositor to window (C2W): + +Describes the direction of communication originating from +a compositor and directed towards a specific window: + +``COMPOSITOR -> WINDOW`` + +### Window to compositor (W2C): + +Describes the direction of communication originating from +a specific window to a compositor running on the system: + +``WINDOW -> COMPOSITOR`` + +## Architecture + +``` ++-------------+ +| LIBGFX | ++-------------+ + ^ + | linked with libgfx + V ++-------------+ +| COMPOSITOR | ++-------------+ <---+ signal + | | | | + | | | | c2w: <winop: e.g., close> + | | | | w2c: <winop to accept: e.g., close> + WIN WIN WIN <---+ +``` + +### C2W signal flow: + +``` +-- CLOSE SIGNAL EXAMPLE -- + +WINDOW RECEIVES CLOSE SIGNAL + | + ECHO BACK TO COMPOSITOR + | + YES ---+--- NO + | | + | V + | nothing happens + | + V + window is destroyed by compositor +``` + +## Libgfx + +The Hyra userspace includes ``libgfx`` which is a low-level graphics library aimed +to facilitate drawing on the screen and performing various graphical operations while +decoupling from the concept of compositors, windows and the ODA as a whole. In other words, +libgfx has no knowledge of anything outside of the framebuffer and itself. + +The following is an example of how one may draw a yellow square at +x/y (30,0): + +```c +#include <libgfx/gfx.h> /* Common routines/defs */ +#include <libgfx/draw.h> /* Drawing related routines/defs */ + +int +main(void) +{ + struct gfx_ctx ctx; + struct gfx_shape sh = GFX_SHAPE_DEFAULT; + int error; + + /* Set the x/y and color */ + sh.x = 30; + sh.y = 0; + sh.color = GFX_YELLOW + + error = gfx_init(&ctx); + if (error < 0) { + printf("gfx_init returned %d\n", error); + return error; + } + + /* Draw the square and cleanup */ + gfx_draw_shape(&ctx, &sh); + gfx_cleanup(&ctx); + return 0; +} +``` + +## Liboda + +The Hyra userspace includes the ``liboda`` library which includes various +interfaces conforming to the OSMORA Display Architecture (ODA). + +### Linking a compositor with liboda + +In order for an ODA compliant compositor to reference library +symbols for ``liboda``, it should use the following linker flags: + +``... -loda -logfx`` + +### ODA Session + +For the ODA library to keep track of state, it relies on an ``oda_state`` +structure defined in ``liboda/oda.h``. Additionally, in order for any ODA +library calls to be made, the compositor must initialize the library with +``oda_init()`` like in the following example: + +```c +#include <liboda/oda.h> + +struct oda_state state; +int error; + +/* Returns 0 on success */ +error = oda_init(&state); +... +``` + +Upon failure of ``oda_init()`` a negative POSIX errno value +is returned (see ``sys/errno.h``). + +### Using liboda to request windows + +A compositor may request windows from the ODA by using +``oda_reqwin()`` like in the following example: + +```c +#include <liboda/oda.h> + +... +struct oda_wattr wattr; +struct oda_state state; + +... + +wattr.session = &state; +wattr.parent = NULL; +wattr.bg = GFX_YELLOW; +wattr.x = 200; +wattr.y = 150; +wattr.w = 120; +wattr.h = 300; + +/* Returns 0 on success */ +error = oda_reqwin(&wattr, &win); +``` + +Arguments passed to ``oda_reqwin()`` are first stored in a ``struct oda_wattr`` +structure to minimize the number of parameters used in the function signature. + +Upon failure of ``oda_reqwin()`` a negative POSIX errno value +is returned (see ``sys/errno.h``). + +### Input management + +The liboda library additionally provides an input API that facilitates +management of user input (e.g., keyboard). + +(See ``liboda/input.h``) + +#### The ``oda_key`` structure + +ODA provides a standard description of keys received from a keyboard +device. Keyboard input is represented by the ``oda_key`` structure shown +below: + +```c +struct oda_key { + uint16_t type; + uint8_t scancode; + char ch; + ... +}; +``` + +The ``type`` field describes the key type, valid key types can be +found within the ``ODA_KEY_*`` definitions in ``liboda/input.h``. + +The ``scancode`` field contains the raw keyboard scancode received +from the device. + +The ``ch`` field contains the ASCII representation of the input received +from the device. + +#### The ``oda_kbd`` structure + +ODA represents keyboard devices through the ``oda_kbd`` structure found +in ``liboda/input.h``. This structure contains callbacks that are set up +by the compositor to be invoked when their respective keyboard related +event occurs. |