commit - /dev/null
commit + 61d67952bb7d89f33f258407967f721c83a3bdb6
blob - /dev/null
blob + 3fe7ac0b03427301f6a7db54eee5351014c539d2 (mode 644)
--- /dev/null
+++ README
+This directory contains the source code for the ria
+graphics system that can be built and run on OpenBSD
+when drm is turned off.
+
+prot.h Protocol used by libria
+ria/ The server
+libria/ Interface to comunicate with ria
+
+The goal of this system is to have a simple graphics
+system that can be easily understood with very little
+code.
blob - /dev/null
blob + 865ecbcdaae71fb7e4353f4dca931f34451adcca (mode 644)
--- /dev/null
+++ TODO
+- Emulate Plan9 by making the window system both a
+ a shell and an image. Look at openpty(3) and
+ pty(4). This will allow nested instances.
+
+- Define a proper and well documented protocol :^).
+
+- Make a couple of demo programs using the protocol.
blob - /dev/null
blob + 20d4bcef726a4cbf96ffbb605738e9ba4a899377 (mode 644)
--- /dev/null
+++ libria/LICENSE
+Copyright (c) 2026 Onana Onana Xavier Manuel <xavier@onana.net>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
blob - /dev/null
blob + 4588c35f26e9400c256ab1d9c2e6c8ddc5724074 (mode 644)
--- /dev/null
+++ libria/Makefile
+CC=cc
+LIB=libria
+SRCS=\
+ draw.c
+OBJS=${SRCS:.c=.o}
+PREFIX=/usr/local
+CFLAGS=-O0 -Wall -Werror -I ../
+HDRS=\
+ draw.h\
+ event.h\
+ ../prot.h
+
+${LIB}: ${OBJS} ${HDRS}
+ ar rc ${LIB}.a ${OBJS}
+
+install: ${LIB}
+ install -d ${PREFIX} ${PREFIX}/include/ria
+ install -m 644 ${HDRS} ${PREFIX}/include/ria
+ install -m 644 ${LIB}.a ${PREFIX}/lib
+
+uninstall:
+ rm -rf ${PREFIX}/include/ria
+ rm -rf ${PREFIX}/lib/${LIB}.a
+
+.c.o:
+ ${CC} -c $< -o $@ ${CFLAGS}
+
+clean:
+ rm -rf ${OBJS} ${LIB}.a
+
+.PHONY: clean
blob - /dev/null
blob + 09011e6ee5930249e0cd4db1af20daad61e3695e (mode 644)
--- /dev/null
+++ libria/draw.c
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/un.h>
+#include <sys/socket.h>
+
+#include "prot.h"
+#include "draw.h"
+
+static int _connect(void);
+
+struct ria_display *ria_display;
+
+int
+ria_init()
+{
+ if (_connect() == -1)
+ return -1;
+
+ return 0;
+}
+
+int
+ria_draw()
+{
+ struct msg dmsg;
+
+ dmsg.type = MSG_TYPE_DRAW;
+ dmsg.len = sizeof(dmsg);
+
+ if (send(ria_display->fd, &dmsg, dmsg.len, 0) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+_connect()
+{
+ struct sockaddr_un addr;
+
+ if (ria_display != NULL) {
+ errno = EPERM;
+ return -1;
+ }
+
+ if ((ria_display = calloc(1, sizeof(*ria_display))) == NULL)
+ return -1;
+
+ if ((ria_display->fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+ memset(addr.sun_path, 0, sizeof(addr.sun_path));
+ strncpy(addr.sun_path, RIA_SOCK_PATH, sizeof(addr.sun_path));
+
+ if (connect(ria_display->fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ close(ria_display->fd);
+ free(ria_display);
+ return -1;
+ }
+
+ return 0;
+}
blob - /dev/null
blob + 5d22f9421f0836d35b1a637f27a0a0fe548798b6 (mode 644)
--- /dev/null
+++ libria/draw.h
+#ifndef _RIA_DRAW_H_
+#define _RIA_DRAW_H_
+
+struct ria_display {
+ int fd;
+};
+
+int ria_init(void);
+int ria_draw(void);
+
+
+/*
+ * Global variables
+ */
+extern struct ria_display *ria_display;
+
+#endif
blob - /dev/null
blob + 4237e2d1848d82bf9e16ede9fffe9efa49dfd5d5 (mode 644)
--- /dev/null
+++ libria/event.h
+#ifndef _RIA_EVENT_H_
+#define _RIA_EVENT_H_
+
+#endif
blob - /dev/null
blob + 19b99122f4a2cc2cc6a0bf3110a20d08e92dfb6c (mode 644)
--- /dev/null
+++ prot.h
+#define RIA_SOCK_PATH "/tmp/ria.sock"
+
+enum msg_type {
+ MSG_TYPE_DRAW,
+};
+
+struct msg {
+ enum msg_type type;
+ uint32_t len;
+};
blob - /dev/null
blob + 20d4bcef726a4cbf96ffbb605738e9ba4a899377 (mode 644)
--- /dev/null
+++ ria/LICENSE
+Copyright (c) 2026 Onana Onana Xavier Manuel <xavier@onana.net>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
blob - /dev/null
blob + 0c3d3f212aa575bf622fffd69b5eb30525e9bf0a (mode 644)
--- /dev/null
+++ ria/Makefile
+CC=cc
+BIN=ria
+SRCS=\
+ ria.c\
+ cursor.c\
+ event.c\
+ kmap.c\
+ wsctl.c\
+ fb.c
+
+OBJS=${SRCS:.c=.o}
+CFLAGS=-O0 -Wall -Werror -I ../
+HDRS=\
+ fb.h\
+ wsctl.h\
+ event.h
+
+${BIN}: ${OBJS} ${HDRS}
+ ${CC} ${OBJS} -o ${BIN}
+
+.c.o:
+ ${CC} -fPIE -c $< -o $@ ${CFLAGS}
+
+clean:
+ rm -rf ${BIN} ${BIN}.core ${OBJS}
+
+.PHONY: clean
blob - /dev/null
blob + 34f28370755e3f1e3a70108a7d6750d82667d3e8 (mode 644)
--- /dev/null
+++ ria/README
+This is intended to run on OpenBSD.
+
+Features:
+
+- No drm
+
+- No web browser
+
+- Plenty of screen tearing
+
+- No ttf/otf
+
+- US encoding only
+
+- usb keyboard device only supported
+
+- and more
+
+- No keybinding because i18n sucks
+
+- also, its kinda cool?
+
+Tutorial:
+
+- disable inteldrm/radeondrm
+
+- make
+
+- ria
+
+- ascend
blob - /dev/null
blob + 2c22d89edd26ebfa94da6439d811b57b062e1d00 (mode 644)
--- /dev/null
+++ ria/cursor.c
+#include "fb.h"
+
+void
+button_press(int button)
+{
+ cursor.held[button] = 1;
+}
+
+void
+button_release(int button)
+{
+ cursor.held[button] = 0;
+}
blob - /dev/null
blob + e21f2827e4fdc2ef70f01790ef3584b4b9d14971 (mode 644)
--- /dev/null
+++ ria/event.c
+#include <stdio.h>
+
+#include "event.h"
+
+#define EVENT_QUEUE_SIZE 255
+
+static struct event queue[EVENT_QUEUE_SIZE];
+static size_t head;
+static size_t tail;
+
+void
+event_push(struct event *ev)
+{
+ size_t n = (head + 1) % EVENT_QUEUE_SIZE;
+
+ if (n == tail)
+ return;
+
+ queue[head] = *ev;
+ head = n;
+}
+
+int
+event_pop(struct event *ev)
+{
+ if (head == tail)
+ return -1;
+
+ *ev = queue[tail];
+ tail = (tail + 1) % EVENT_QUEUE_SIZE;
+ return 0;
+}
blob - /dev/null
blob + 20f5100703baaeb641ad8e2a8e91efac2807c34d (mode 644)
--- /dev/null
+++ ria/event.h
+enum event_type {
+ EVENT_TYPE_MOUSE,
+ EVENT_TYPE_KEYBOARD
+};
+
+enum event_list {
+ EVENT_KEY_DOWN,
+ EVENT_KEY_UP,
+ EVENT_MOUSE_MOTION,
+ EVENT_MOUSE_PRESS,
+ EVENT_MOUSE_RELEASE,
+};
+
+struct mouse_event {
+ int type;
+ int x, y;
+ int button;
+};
+
+struct kbd_event {
+ int type;
+ int key;
+};
+
+struct event {
+ enum event_type type;
+
+ union {
+ struct mouse_event mouse;
+ struct kbd_event kbd;
+ };
+};
+
+void event_push(struct event*);
+int event_pop(struct event*);
blob - /dev/null
blob + 8849d4de6d84a880961be9319d2b5ab1f9c50bbf (mode 644)
--- /dev/null
+++ ria/fb.c
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "fb.h"
+
+struct fbinfo *fb;
+struct cursor cursor;
+
+int
+intersects(struct rectangle *, struct rectangle *);
+
+/*
+ * Expects 32 bits
+ */
+void
+fill(unsigned int value)
+{
+ uint32_t *data = (uint32_t *)fb->bdat;
+
+ /*
+ * 4 channels ARGB
+ */
+ for (size_t i = 0; i < fb->bytes/4; i++)
+ data[i] = value;
+
+ damage(&(struct rectangle) { 0, 0, fb->width, fb->height });
+}
+
+void
+draw_cursor()
+{
+ int x1 = cursor.x;
+ int y1 = cursor.y;
+
+ int x2 = cursor.x + CURSOR_WIDTH;
+ int y2 = cursor.y + CURSOR_HEIGHT;
+
+ uint32_t *dat = (uint32_t *)fb->dat;
+
+ /* Clamp */
+ if (x2 > fb->width) x2 = fb->width;
+ if (y2 > fb->height) y2 = fb->height;
+
+ for (int j = y1; j < y2; j++) {
+ int idx = j * fb->width + x1;
+ memcpy(dat + idx, cursor.bits, (x2 - x1) * 4);
+ }
+}
+
+void
+damage(struct rectangle *rect)
+{
+ int x1 = rect->x1 < rect->x2 ? rect->x1 : rect->x2;
+ int y1 = rect->y1 < rect->y2 ? rect->y1 : rect->y2;
+ int x2 = rect->x1 < rect->x2 ? rect->x2 : rect->x1;
+ int y2 = rect->y1 < rect->y2 ? rect->y2 : rect->y1;
+
+ /* CLAMP */
+ if (x1 > fb->width) x1 = fb->width;
+ if (x2 > fb->width) x2 = fb->width;
+ if (y1 > fb->height) y1 = fb->height;
+ if (y2 > fb->height) y2 = fb->height;
+
+ if (x1 < 0) { x2 = (x2 - x1); x1 = 0; }
+ if (y1 < 0) { y2 = (y2 - y1); y1 = 0; }
+
+ uint32_t *bdat = (uint32_t *)fb->bdat;
+ uint32_t *dat = (uint32_t *)fb->dat;
+
+ for (int j = y1; j < y2; j++) {
+ int idx = j * fb->width + x1;
+ memcpy(dat + idx, bdat + idx, (x2 - x1) * 4); /* 4 channels */
+ }
+}
+
+
+int intersects(struct rectangle *a, struct rectangle *b)
+{
+ return (a->x1 <= b->x2 && a->x2 >= b->x2) && (a->y1 <= b->y2 && a->y2 >= b->y1);
+}
blob - /dev/null
blob + b1b7b1f224308bbf60c20abd12306a19a4a191d4 (mode 644)
--- /dev/null
+++ ria/fb.h
+#include <stdlib.h>
+
+#define CURSOR_WIDTH 16
+#define CURSOR_HEIGHT 16
+
+#define BUTTON_1 0
+#define BUTTON_2 1
+#define BUTTON_3 2
+
+struct cursor {
+ unsigned char bits[CURSOR_WIDTH * CURSOR_HEIGHT * 4];
+ unsigned char held[3];
+ int16_t x;
+ int16_t y;
+};
+
+struct rectangle {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+};
+
+struct fbinfo {
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ void *dat;
+ void *bdat; /* back-buffer */
+ size_t bytes;
+};
+
+void fill(unsigned int);
+void draw_cursor();
+void damage(struct rectangle *);
+
+void button_press(int);
+void button_release(int);
+
+extern struct fbinfo *fb;
+extern struct cursor cursor;
blob - /dev/null
blob + 5e6dfb744c4e93a1e07353ce7fc4a5d72043639d (mode 644)
--- /dev/null
+++ ria/kbd.h
+struct kbd_map {
+ int keysym;
+};
+
+int get_kbd_map(struct kbd_map **, unsigned int, int);
blob - /dev/null
blob + 98b14321611425116ca425cff8db37ac7581f2b0 (mode 644)
--- /dev/null
+++ ria/kmap.c
+#include <stdio.h>
+#include <stdlib.h>
+#include <dev/wscons/wsksymdef.h>
+#include "kbd.h"
+
+/*
+ * Source: /usr/include/dev/usb/ukbmap.c
+ *
+ * This is shit
+ */
+static struct kbd_map usb_us[] = {
+/* keysym */
+ [0x04] = { KS_a },
+ [0x05] = { KS_b },
+ [0x06] = { KS_c },
+ [0x07] = { KS_d },
+ [0x08] = { KS_e },
+ [0x09] = { KS_f },
+ [0x0A] = { KS_g },
+ [0x0B] = { KS_h },
+ [0x0C] = { KS_i },
+ [0x0D] = { KS_j },
+ [0x0E] = { KS_k },
+ [0x0F] = { KS_l },
+ [0x10] = { KS_m },
+ [0x11] = { KS_n },
+ [0x12] = { KS_o },
+ [0x13] = { KS_p },
+ [0x14] = { KS_q },
+ [0x15] = { KS_r },
+ [0x16] = { KS_s },
+ [0x17] = { KS_t },
+ [0x18] = { KS_u },
+ [0x19] = { KS_v },
+ [0x1A] = { KS_w },
+ [0x1B] = { KS_x },
+ [0x1C] = { KS_y },
+ [0x1D] = { KS_z },
+ [0x1E] = { KS_1 },
+ [0x1F] = { KS_2 },
+ [0x20] = { KS_3 },
+ [0x21] = { KS_4 },
+ [0x22] = { KS_5 },
+ [0x23] = { KS_6 },
+ [0x24] = { KS_7 },
+ [0x25] = { KS_8 },
+ [0x26] = { KS_9 },
+ [0x27] = { KS_0 },
+ [0x28] = { KS_Return },
+ [0x29] = { KS_Escape },
+ [0x2A] = { KS_Delete },
+ [0x2B] = { KS_Tab },
+ [0x2C] = { KS_space },
+ [0x2D] = { KS_minus },
+ [0x2E] = { KS_equal },
+ [0x2F] = { KS_bracketleft },
+ [0x30] = { KS_bracketright },
+ [0x31] = { KS_backslash },
+ [0x32] = { KS_backslash },
+ [0x33] = { KS_semicolon },
+ [0x34] = { KS_apostrophe },
+ [0x35] = { KS_grave },
+ [0x36] = { KS_comma },
+ [0x37] = { KS_period },
+ [0x38] = { KS_slash },
+ [0x39] = { KS_Caps_Lock },
+ [0x3A] = { KS_f1 },
+ [0x3B] = { KS_f2 },
+ [0x3C] = { KS_f3 },
+ [0x3D] = { KS_f4 },
+ [0x3E] = { KS_f5 },
+ [0x3F] = { KS_f6 },
+ [0x40] = { KS_f7 },
+ [0x41] = { KS_f8 },
+ [0x42] = { KS_f9 },
+ [0x43] = { KS_f10 },
+ [0x44] = { KS_f11 },
+ [0x45] = { KS_f12 },
+ [0x46] = { KS_Print_Screen },
+ [0x47] = { KS_Hold_Screen },
+ [0x48] = { KS_Pause },
+ [0x49] = { KS_Insert },
+ [0x4A] = { KS_Home },
+ [0x4B] = { KS_Prior },
+ [0x4C] = { KS_KP_Delete },
+ [0x4D] = { KS_End },
+ [0x4E] = { KS_Next },
+ [0x4F] = { KS_Right },
+ [0x50] = { KS_Left },
+ [0x51] = { KS_Down },
+ [0x52] = { KS_Up },
+ [0x53] = { KS_Num_Lock },
+ [0x54] = { KS_KP_Divide },
+ [0x55] = { KS_KP_Multiply },
+ [0x56] = { KS_KP_Subtract },
+ [0x57] = { KS_KP_Add },
+ [0x58] = { KS_KP_Enter },
+ [0x59] = { KS_KP_1 },
+ [0x5A] = { KS_KP_2 },
+ [0x5B] = { KS_KP_3 },
+ [0x5C] = { KS_KP_4 },
+ [0x5D] = { KS_KP_5 },
+ [0x5E] = { KS_KP_6 },
+ [0x5F] = { KS_KP_7 },
+ [0x60] = { KS_KP_8 },
+ [0x61] = { KS_KP_9 },
+ [0x62] = { KS_KP_0 },
+ [0x63] = { KS_KP_Delete }, /* 100 don't exists */
+ [0x64] = { KS_Menu },
+ [0x66] = { KS_Cmd_Sleep }, /* 103 either */
+ [0x68] = { KS_f13 },
+ [0x69] = { KS_f14 },
+ [0x6A] = { KS_f15 },
+ [0x6B] = { KS_f16 },
+ [0x6C] = { KS_f17 },
+ [0x6D] = { KS_f18 },
+ [0x6E] = { KS_f19 },
+ [0x6F] = { KS_f20 },
+ [0x70] = { KS_f21 },
+ [0x71] = { KS_f22 },
+ [0x72] = { KS_f23 },
+ [0x73] = { KS_f24 },
+ [0x74] = { KS_Open },
+ [0x75] = { KS_Help },
+ [0x76] = { KS_Props },
+ [0x77] = { KS_Front },
+ [0x78] = { KS_Cmd },
+ [0x79] = { KS_Again },
+ [0x7A] = { KS_Undo },
+ [0x7B] = { KS_Cut },
+ [0x7C] = { KS_Copy },
+ [0x7D] = { KS_Paste },
+ [0x7E] = { KS_Find },
+ [0x7F] = { KS_AudioMute },
+ [0x80] = { KS_AudioRaise },
+ [0x81] = { KS_AudioLower }, /* Keys [130, 223] are empty */
+ [0xE0] = { KS_Control_L },
+ [0xE1] = { KS_Shift_L },
+ [0xE2] = { KS_Alt_L },
+ [0xE3] = { KS_Meta_L },
+ [0xE4] = { KS_Control_R },
+ [0xE5] = { KS_Shift_R },
+ [0xE6] = { KS_Alt_R },
+ [0xE7] = { KS_Meta_R },
+ [0xE8] = { KS_Cmd_BrightnessUp },
+ [0xE9] = { KS_Cmd_BrightnessDown },
+ [0xEA] = { KS_Cmd_KbdBacklightToggle },
+ [0xEB] = { KS_Cmd_KbdBacklightUp },
+ [0xEC] = { KS_Cmd_KbdBacklightDown },
+};
+
+int
+get_kbd_map(struct kbd_map **kmap, unsigned int type, int encoding)
+{
+ size_t size = sizeof(usb_us) / sizeof(*usb_us);
+ *kmap = usb_us;
+ return size;
+}
blob - /dev/null
blob + 26df1a54c2f1d50fa99ea19e36ebb01633ff6594 (mode 644)
--- /dev/null
+++ ria/ria.1
+.Dd $Mdocdate: August 09 2026$
+.Dt RIA 1
+.Os
+.Sh NAME
+.Nm ria
+.Nd rio is amazing
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+was created to emulate some of the functionalities of
+.Xr rio 1
+and window managers like
+.Xr cwm 1
+in order to create a coherent and simple system on
+OpenBSD.
+
+Just as in
+.Xr rio 1
+most operations are handled by the mouse. Keybinding
+is not supported for shortcut and is not planned in the
+future. This is partly to avoid i18n issues and keep the
+system simple.
+.Sh CAVEATS
+For now it only supports 32-bit depth displays and keyboard
+driver support is limited to
+.Xr ukbd 4
+with us encoding.
+
+.Xr pckbd 4
+support will be added later.
+.Sh SEE ALSO
+.Xr cwm 1 ,
+.Xr rio 1
+.Sh AUTHORS
+.An Onana Onana Xavier Manuel Aq Mt xavier@onana.net
blob - /dev/null
blob + f3eee918ea7d3b2b6bf59106d11e3d56588550d0 (mode 644)
--- /dev/null
+++ ria/ria.c
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include <dev/wscons/wsksymdef.h>
+
+#include "wsctl.h"
+#include "event.h"
+#include "fb.h"
+
+static volatile sig_atomic_t running = 1;
+
+void read_kbd(struct kbd_event *);
+void read_mouse(struct mouse_event *);
+
+void int_handler(int);
+
+/*
+ * TODO:
+ * Check ttyname to see if it starts with ttyC[0-N]
+ * to prevent remote execution of ria(1).
+ */
+
+int
+main()
+{
+ struct event ev;
+ int ret;
+
+ signal(SIGTERM, int_handler);
+ signal(SIGINT, int_handler);
+
+ if ((fb = wsctl_init()) == NULL) {
+ return -1;
+ }
+
+ fill(0xFF7F7F7F);
+ draw_cursor();
+
+ while (running) {
+ if ((ret = wsctl_run()) == -1)
+ break;
+
+ while (event_pop(&ev) != -1) {
+ switch (ev.type) {
+ case EVENT_TYPE_KEYBOARD:
+ read_kbd(&ev.kbd);
+ break;
+ case EVENT_TYPE_MOUSE:
+ read_mouse(&ev.mouse);
+ break;
+ }
+ }
+ }
+
+ fill(0);
+ wsctl_exit();
+}
+
+
+void
+read_kbd(struct kbd_event *kev)
+{
+ switch (kev->type) {
+ case EVENT_KEY_DOWN:
+ if (kev->key == KS_q)
+ running = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+read_mouse(struct mouse_event *mev)
+{
+ switch (mev->type) {
+ case EVENT_MOUSE_MOTION: {
+ struct rectangle old;
+
+ old.x1 = cursor.x;
+ old.y1 = cursor.y;
+ old.x2 = old.x1 + CURSOR_WIDTH;
+ old.y2 = old.y1 + CURSOR_HEIGHT;
+
+ cursor.x += mev->x;
+ cursor.y += mev->y;
+
+ if (cursor.x < 0)
+ cursor.x = 0;
+
+ if (cursor.y < 0)
+ cursor.y = 0;
+
+ if (cursor.x >= fb->width)
+ cursor.x = fb->width - 1;
+
+ if (cursor.y >= fb->height)
+ cursor.y = fb->height - 1;
+
+ damage(&old);
+ draw_cursor();
+ break;
+ }
+ case EVENT_MOUSE_PRESS:
+ if (mev->button >= 0 && mev->button < 3)
+ button_press(mev->button);
+ break;
+ case EVENT_MOUSE_RELEASE:
+ if (mev->button >= 0 && mev->button < 3)
+ button_release(mev->button);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+int_handler(int sig)
+{
+ running = 0;
+}
blob - /dev/null
blob + 9e8340f2a0f48187013f4f16af117daa104484e4 (mode 644)
--- /dev/null
+++ ria/wsctl.c
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#include <sys/un.h>
+#include <sys/socket.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsksymdef.h>
+
+#include "prot.h"
+#include "fb.h"
+#include "kbd.h"
+#include "event.h"
+#include "wsctl.h"
+
+static int init_kbd(void);
+static int init_mouse(void);
+static int read_kbd(void);
+static int read_mouse(void);
+static int read_cmd(void);
+static int sock_init(void);
+static void sock_exit(void);
+
+static struct {
+ int fd;
+ struct {
+ int fd;
+ } mouse;
+ struct {
+ int fd;
+ int maplen;
+ struct kbd_map *map;
+ } kbd;
+
+ struct {
+ int fd;
+ socklen_t len;
+ struct sockaddr_un addr;
+ } sock;
+
+ struct fbinfo *fb;
+} wsctl;
+
+struct fbinfo*
+wsctl_init()
+{
+ int mode = WSDISPLAYIO_MODE_DUMBFB;
+ struct wsdisplay_fbinfo fbinfo;
+ struct fbinfo *fbi;
+
+ if ((fbi = malloc(sizeof(*fbi))) == 0) {
+ fprintf(stderr, "failed to allocate fbinfo\n");
+ return NULL;
+ }
+
+ /*
+ * TODO:
+ * Open the active tty instead of /dev/ttyC0
+ */
+
+ if((wsctl.fd = open("/dev/ttyC4", O_RDWR | O_EXCL)) == -1) {
+ perror("failed to open tty file descriptor");
+ free(fbi);
+ return NULL;
+ }
+
+ if (init_mouse() == -1) {
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+ if (init_kbd() == -1) {
+ close(wsctl.mouse.fd);
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+ if (sock_init() == -1) {
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ }
+
+ if (ioctl(wsctl.fd, WSDISPLAYIO_GINFO, &fbinfo) == -1) {
+ perror("failed to fetch display information");
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+ fbi->height = fbinfo.height;
+ fbi->width = fbinfo.width;
+ fbi->depth = fbinfo.depth;
+
+ /*
+ * For now we only support ARGB
+ */
+ if (fbi->depth != 32) {
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ errno=ENOTSUP;
+ return NULL;
+ }
+
+ if ((fbi->bdat = calloc(1, fbi->width * fbi->height * fbi->depth / 8)) == NULL) {
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+ if (ioctl(wsctl.fd, WSDISPLAYIO_SMODE, &mode) == -1) {
+ perror("could not initialize the framebuffer");
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+ fbi->bytes = fbi->width * fbi->height * fbi->depth / 8;
+
+ fbi->dat = mmap(NULL, fbi->bytes, PROT_WRITE | PROT_READ, MAP_SHARED, wsctl.fd, 0);
+
+ if (fbi->dat == MAP_FAILED) {
+ perror("could not map frame buffer");
+ mode = WSDISPLAYIO_MODE_EMUL;
+ ioctl(wsctl.fd, WSDISPLAYIO_SMODE, &mode);
+ close(wsctl.mouse.fd);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(fbi);
+ return NULL;
+ }
+
+
+ cursor.x = fbi->width / 2;
+ cursor.y = fbi->height / 2;
+ wsctl.fb = fbi;
+
+ return fbi;
+}
+
+void
+wsctl_exit()
+{
+ int mode;
+
+ if (ioctl(wsctl.fd, WSDISPLAYIO_GMODE, &mode) == -1)
+ perror("failed to get video mode");
+ else {
+ if (mode != WSDISPLAYIO_MODE_EMUL) {
+ mode = WSDISPLAYIO_MODE_EMUL;
+ munmap(wsctl.fb->dat, wsctl.fb->bytes);
+
+ if (ioctl(wsctl.fd, WSDISPLAYIO_SMODE, &mode) == -1)
+ perror("failed to smode to emul");
+ }
+ }
+
+ close(wsctl.mouse.fd);
+ free(wsctl.fb->bdat);
+ close(wsctl.kbd.fd);
+ close(wsctl.fd);
+ free(wsctl.fb);
+ sock_exit();
+}
+
+int
+wsctl_run()
+{
+ struct pollfd pfds[3];
+ int ret;
+
+ pfds[0].fd = wsctl.mouse.fd;
+ pfds[1].fd = wsctl.kbd.fd;
+ pfds[2].fd = wsctl.sock.fd;
+
+ pfds[0].events = POLLIN;
+ pfds[1].events = POLLIN;
+ pfds[2].events = POLLIN;
+
+ ret = poll(pfds, 3, -1);
+
+ if (ret == -1) {
+ if (errno == EINTR)
+ return 0;
+
+ perror("poll");
+ return -1;
+ }
+
+ if (pfds[0].revents & POLLIN)
+ read_mouse();
+
+ if (pfds[1].revents & POLLIN)
+ read_kbd();
+
+ if (pfds[2].revents & POLLIN)
+ read_cmd();
+
+ return 0;
+}
+
+static int
+init_mouse()
+{
+ if ((wsctl.mouse.fd = open("/dev/wsmouse", O_RDONLY | O_NONBLOCK)) == -1) {
+ perror("failed to open mouse");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * There is probably a better way to do this but unfortunately I did
+ * not found 1. The method is getting the encoding, getting the type
+ * usb/pckb etc, and then mapping the ev.value to a lookup table to
+ * get a keysym.
+ *
+ * This makes it so we have to create a lookup table for every single
+ * device and every encoding. For now only usbkb and us encoding will
+ * be supported.
+ */
+static int
+init_kbd()
+{
+ kbd_t encoding;
+ u_int type;
+
+ if ((wsctl.kbd.fd = open("/dev/wskbd", O_RDONLY | O_NONBLOCK)) == -1) {
+ perror("failed to open keyboard");
+ return -1;
+ }
+
+ if (ioctl(wsctl.kbd.fd, WSKBDIO_GETENCODING, &encoding) == -1) {
+ close(wsctl.kbd.fd);
+ return -1;
+ }
+
+ if (ioctl(wsctl.kbd.fd, WSKBDIO_GTYPE, &type) == -1) {
+ close(wsctl.kbd.fd);
+ return -1;
+ }
+
+ switch (type) {
+ case WSKBD_TYPE_USB:
+ break;
+ default:
+ close(wsctl.kbd.fd);
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ switch (encoding) {
+ case KB_US:
+ break;
+ default:
+ close(wsctl.kbd.fd);
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ wsctl.kbd.maplen = get_kbd_map(&wsctl.kbd.map, encoding, type);
+
+ return 0;
+}
+
+
+static int
+read_mouse()
+{
+ unsigned char flags[WSCONS_EVENT_SYNC + 1] = { 0 };
+ struct event mev = { 0 };
+ struct wscons_event ev;
+ int n;
+
+ while ((n = read(wsctl.mouse.fd, &ev, sizeof(ev))) > 0) {
+ switch (ev.type) {
+ case WSCONS_EVENT_MOUSE_DELTA_X:
+ mev.mouse.x = ev.value;
+ break;
+ case WSCONS_EVENT_MOUSE_DELTA_Y:
+ mev.mouse.y = -ev.value;
+ break;
+ /* Event ready */
+ case WSCONS_EVENT_SYNC:
+ break;
+ /* Unsupported events */
+ case WSCONS_EVENT_MOUSE_UP:
+ mev.mouse.button = ev.value;
+ break;
+ case WSCONS_EVENT_MOUSE_DOWN:
+ mev.mouse.button = ev.value;
+ break;
+ case WSCONS_EVENT_MOUSE_DELTA_Z:
+ case WSCONS_EVENT_MOUSE_DELTA_W:
+ case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
+ case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
+ case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
+ case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
+ continue;
+ }
+
+ flags[ev.type] = 1;
+
+ if (flags[WSCONS_EVENT_SYNC] == 1) {
+ if (flags[WSCONS_EVENT_MOUSE_DELTA_X] || flags[WSCONS_EVENT_MOUSE_DELTA_Y]) {
+ mev.mouse.type = EVENT_MOUSE_MOTION;
+ mev.type = EVENT_TYPE_MOUSE;
+
+ flags[WSCONS_EVENT_MOUSE_DELTA_X] = 0;
+ flags[WSCONS_EVENT_MOUSE_DELTA_Y] = 0;
+ }
+
+ if (flags[WSCONS_EVENT_MOUSE_DOWN]) {
+ mev.mouse.type = EVENT_MOUSE_PRESS;
+ mev.type = EVENT_TYPE_MOUSE;
+
+ flags[WSCONS_EVENT_MOUSE_DOWN] = 0;
+ }
+
+ if (flags[WSCONS_EVENT_MOUSE_UP]) {
+ mev.mouse.type = EVENT_MOUSE_RELEASE;
+ mev.type = EVENT_TYPE_MOUSE;
+
+ flags[WSCONS_EVENT_MOUSE_UP] = 0;
+ }
+
+ event_push(&mev);
+ flags[WSCONS_EVENT_SYNC] = 0;
+ }
+ }
+ return 0;
+}
+
+static int
+read_kbd()
+{
+ struct wscons_event ev;
+ int keysym;
+ int n;
+
+ while ((n = read(wsctl.kbd.fd, &ev, sizeof(ev))) > 0) {
+ struct event push = { 0 };
+ push.type = EVENT_TYPE_KEYBOARD;
+
+ switch (ev.type) {
+ case WSCONS_EVENT_KEY_DOWN:
+ if (ev.value < 0 || ev.value >= wsctl.kbd.maplen)
+ continue;
+
+ keysym = wsctl.kbd.map[ev.value].keysym;
+ push.kbd.type = EVENT_KEY_DOWN;
+ push.kbd.key = keysym;
+ break;
+ case WSCONS_EVENT_KEY_UP:
+ if (ev.value < 0 || ev.value >= wsctl.kbd.maplen)
+ continue;
+
+ keysym = wsctl.kbd.map[ev.value].keysym;
+ push.kbd.type = EVENT_KEY_UP;
+ push.kbd.key = keysym;
+ break;
+ /* Not supported */
+ default:
+ continue;
+ }
+
+ event_push(&push);
+ }
+ return 0;
+}
+
+int
+read_cmd()
+{
+ return 0;
+}
+
+
+static int
+sock_init()
+{
+ if ((wsctl.sock.fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
+ return -1;
+
+ wsctl.sock.addr.sun_family = AF_UNIX;
+ memset(wsctl.sock.addr.sun_path, 0, sizeof(wsctl.sock.addr.sun_path));
+ strncpy(wsctl.sock.addr.sun_path, RIA_SOCK_PATH, sizeof(wsctl.sock.addr.sun_path));
+
+ wsctl.sock.len = sizeof(wsctl.sock.addr);
+
+ if (bind(wsctl.sock.fd, (struct sockaddr *)&wsctl.sock.addr, wsctl.sock.len) == -1) {
+ close(wsctl.sock.fd);
+ return -1;
+ }
+
+ if (listen(wsctl.sock.fd, SOMAXCONN)) {
+ perror("failed to listen");
+ close(wsctl.sock.fd);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+sock_exit()
+{
+ unlink(RIA_SOCK_PATH);
+}
blob - /dev/null
blob + 53028ef6deb1cf043d22636af2f10570970397b5 (mode 644)
--- /dev/null
+++ ria/wsctl.h
+struct fbinfo *wsctl_init(void);
+void wsctl_exit(void);
+int wsctl_run(void);