summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-03-04 19:11:42 -0500
committerBenji Dial <benji6283@gmail.com>2021-03-04 19:11:42 -0500
commit406af09ade55553e2b064506c3ba3c89bd965d73 (patch)
treedd6da93bc329d6b1097aa1afcde2af19491dfc8e /src
parent86af7f631080bc4b45846bd7f382c4cedcbec2b4 (diff)
downloadportland-os-406af09ade55553e2b064506c3ba3c89bd965d73.tar.gz
start of a c++ widget toolkit, c++ runtime
Diffstat (limited to 'src')
-rw-r--r--src/shared/include/winact.h15
-rw-r--r--src/user/include/cxx/raleigh/runtime.h12
-rw-r--r--src/user/include/cxx/raleigh/util.h15
-rw-r--r--src/user/include/cxx/raleigh/w/label.h24
-rw-r--r--src/user/include/cxx/raleigh/w/padding.h20
-rw-r--r--src/user/include/cxx/raleigh/widget.h27
-rw-r--r--src/user/include/cxx/raleigh/window.h27
-rw-r--r--src/user/include/cxx/structs/dllist.h39
-rw-r--r--src/user/include/knob/block.h8
-rw-r--r--src/user/include/knob/heap.h8
-rw-r--r--src/user/include/libfont/fonts.h8
-rw-r--r--src/user/include/pland/pcrt.h8
-rw-r--r--src/user/include/pland/syscall.h8
-rw-r--r--src/user/raleigh/runtime.cpp21
-rw-r--r--src/user/raleigh/util.cpp6
-rw-r--r--src/user/raleigh/w/label.cpp27
-rw-r--r--src/user/raleigh/w/padding.cpp31
-rw-r--r--src/user/raleigh/window.cpp35
-rw-r--r--src/user/rhello/main.cpp13
-rw-r--r--src/user/runtimes/cxx/extra.asm7
-rw-r--r--src/user/runtimes/cxx/extra.ld5
21 files changed, 356 insertions, 8 deletions
diff --git a/src/shared/include/winact.h b/src/shared/include/winact.h
index 8b32d00..9486efc 100644
--- a/src/shared/include/winact.h
+++ b/src/shared/include/winact.h
@@ -3,6 +3,12 @@
#include <keypack.h>
+struct mouse_packet {
+ uint16_t y;
+ uint16_t x;
+ enum mouse_button {LEFT, RIGHT, MIDDLE} which;
+};
+
struct window_action {
enum {
NOT_READY,
@@ -15,14 +21,7 @@ struct window_action {
} action_type;
union {
struct key_packet as_key;
- struct {
- //0, 0 is upper-left-most pixel not counting border
- //packets are also sent for the border pixels,
- // so this may be a negative value in those cases
- int16_t y;
- int16_t x;
- enum mouse_button {LEFT, RIGHT, MIDDLE} which;
- } as_mouse;
+ struct mouse_packet as_mouse;
};
} __attribute__ ((__packed__));
diff --git a/src/user/include/cxx/raleigh/runtime.h b/src/user/include/cxx/raleigh/runtime.h
new file mode 100644
index 0000000..92bd230
--- /dev/null
+++ b/src/user/include/cxx/raleigh/runtime.h
@@ -0,0 +1,12 @@
+#ifndef RALEIGH_RUNTIME_H
+#define RALEIGH_RUNTIME_H
+
+#include <raleigh/window.h>
+#include <structs/dllist.h>
+
+namespace raleigh {
+ void start_runtime() __attribute__ ((noreturn));
+ extern dllist<window &> open_windows;
+}
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/raleigh/util.h b/src/user/include/cxx/raleigh/util.h
new file mode 100644
index 0000000..d2ed13d
--- /dev/null
+++ b/src/user/include/cxx/raleigh/util.h
@@ -0,0 +1,15 @@
+#ifndef RALEIGH_UTIL_H
+#define RALEIGH_UTIL_H
+
+#include <stdint.h>
+
+#define RGB(R, G, B) ((_pixel_t){.r = 0x##R, .g = 0x##G, .b = 0x##B})
+
+struct coord {
+ uint32_t x;
+ uint32_t y;
+ coord(uint32_t x, uint32_t y);
+ coord();
+};
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/raleigh/w/label.h b/src/user/include/cxx/raleigh/w/label.h
new file mode 100644
index 0000000..51bf541
--- /dev/null
+++ b/src/user/include/cxx/raleigh/w/label.h
@@ -0,0 +1,24 @@
+#ifndef RALEIGH_W_LABEL_H
+#define RALEIGH_W_LABEL_H
+
+#include <raleigh/widget.h>
+#include <libfont/fonts.h>
+
+namespace raleigh {
+ class label : public widget {
+ public:
+ //this pointer is used directly, and the contents of the string should not be changed afterward
+ label(const char *value, const char *font="fixed-10",
+ _pixel_t bg=RGB(bf, bf, bf), _pixel_t fg=RGB(00, 00, 00));
+
+ void notify_window_change() override;
+ void paint(_pixel_t *pixbuf, uint32_t pitch) override;
+ private:
+ const char *const value;
+ const struct font_info *const fi;
+ const _pixel_t bg;
+ const _pixel_t fg;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/raleigh/w/padding.h b/src/user/include/cxx/raleigh/w/padding.h
new file mode 100644
index 0000000..108cd28
--- /dev/null
+++ b/src/user/include/cxx/raleigh/w/padding.h
@@ -0,0 +1,20 @@
+#ifndef RALEIGH_W_PADDING_H
+#define RALEIGH_W_PADDING_H
+
+#include <raleigh/widget.h>
+
+namespace raleigh {
+ class padding : public widget {
+ public:
+ padding(uint32_t pad_by, _pixel_t color, widget &inner);
+
+ void notify_window_change() override;
+ void paint(_pixel_t *pixbuf, uint32_t pitch) override;
+ private:
+ uint32_t pad_by;
+ _pixel_t color;
+ widget &inner;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h
new file mode 100644
index 0000000..1839333
--- /dev/null
+++ b/src/user/include/cxx/raleigh/widget.h
@@ -0,0 +1,27 @@
+#ifndef RALEIGH_WIDGET_H
+#define RALEIGH_WIDGET_H
+
+namespace raleigh {
+ class widget;
+}
+
+#include <raleigh/window.h>
+#include <pland/syscall.h>
+#include <raleigh/util.h>
+
+namespace raleigh {
+ class widget {
+ public:
+ coord size;
+
+ //set by window class (or parent widget)
+ window *w;
+ coord window_offset;
+
+ //called by window class (or parent widget)
+ virtual void notify_window_change() = 0;
+ virtual void paint(_pixel_t *pixbuf, uint32_t pitch) = 0;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/raleigh/window.h b/src/user/include/cxx/raleigh/window.h
new file mode 100644
index 0000000..7e45e22
--- /dev/null
+++ b/src/user/include/cxx/raleigh/window.h
@@ -0,0 +1,27 @@
+#ifndef RALEIGH_WINDOW_H
+#define RALEIGH_WINDOW_H
+
+namespace raleigh {
+ class window;
+}
+
+#include <raleigh/widget.h>
+#include <pland/syscall.h>
+#include <raleigh/util.h>
+
+namespace raleigh {
+ class window {
+ public:
+ window(widget &root);
+ void notify_needs_paint(widget &from);
+ enum try_actions_return_t {NONE, GOOD, DELETE};
+ try_actions_return_t try_actions();
+ private:
+ _window_handle_t handle;
+ _pixel_t *pixbuf;
+ coord size;
+ widget &root;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/user/include/cxx/structs/dllist.h b/src/user/include/cxx/structs/dllist.h
new file mode 100644
index 0000000..5783364
--- /dev/null
+++ b/src/user/include/cxx/structs/dllist.h
@@ -0,0 +1,39 @@
+#ifndef STRUCTS_DLLIST_H
+#define STRUCTS_DLLIST_H
+
+template<class data>
+class dllist {
+public:
+ class node {
+ public:
+ node *next;
+ node *prev;
+ data d;
+ node(node *next, node *prev, data d)
+ : next(next), prev(prev), d(d) {}
+ };
+ node *first;
+
+ dllist() : first(0) {}
+
+ void add_front(data d) {
+ node *const n = new node(first, 0, d);
+ if (first)
+ first->prev = n;
+ first = n;
+ }
+
+ //return previous, or zero if this is the first
+ node *remove_in_place(node *n) {
+ if (n == first)
+ first = n->next;
+ if (n->next)
+ n->next->prev = n->prev;
+ if (n->prev)
+ n->prev->next = n->next;
+ delete n;
+ return n->prev;
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/src/user/include/knob/block.h b/src/user/include/knob/block.h
index 1231a6d..565c334 100644
--- a/src/user/include/knob/block.h
+++ b/src/user/include/knob/block.h
@@ -1,6 +1,10 @@
#ifndef KNOB_BLOCK_H
#define KNOB_BLOCK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <stdbool.h>
#include <stdint.h>
@@ -24,4 +28,8 @@ bool strequ(const char *a, const char *b) __attribute__ ((pure));
//this replacement happens in place, with no memory allocation
void str_trunc_fill(char *str, uint32_t len);
+#ifdef __cplusplus
+}
+#endif
+
#endif \ No newline at end of file
diff --git a/src/user/include/knob/heap.h b/src/user/include/knob/heap.h
index 32dc44c..c0d7006 100644
--- a/src/user/include/knob/heap.h
+++ b/src/user/include/knob/heap.h
@@ -1,9 +1,17 @@
#ifndef KNOB_HEAP_H
#define KNOB_HEAP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <stdint.h>
void *get_block(uint32_t bytes) __attribute__ ((malloc));
void free_block(void *block);
+#ifdef __cplusplus
+}
+#endif
+
#endif \ No newline at end of file
diff --git a/src/user/include/libfont/fonts.h b/src/user/include/libfont/fonts.h
index f7ed3e1..629ed5a 100644
--- a/src/user/include/libfont/fonts.h
+++ b/src/user/include/libfont/fonts.h
@@ -1,6 +1,10 @@
#ifndef LIBFONT_FONTS_H
#define LIBFONT_FONTS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <pland/syscall.h>
#include <stdbool.h>
@@ -21,4 +25,8 @@ struct font_info *get_font(const char *name);
//pitch is in pixels
void put_char(const struct font_info *font, char ch, _pixel_t *pb_ptr, uint32_t pb_pitch, _pixel_t bg, _pixel_t fg);
+#ifdef __cplusplus
+}
+#endif
+
#endif \ No newline at end of file
diff --git a/src/user/include/pland/pcrt.h b/src/user/include/pland/pcrt.h
index 795738e..6581cbe 100644
--- a/src/user/include/pland/pcrt.h
+++ b/src/user/include/pland/pcrt.h
@@ -1,6 +1,10 @@
#ifndef PLAND_PCRT_H
#define PLAND_PCRT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <pland/syscall.h>
#define BEFORE_MAIN(f) \
@@ -19,4 +23,8 @@ extern _task_handle_t calling_task;
extern _task_handle_t stdio_task;
extern _task_handle_t this_task;
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index 3c4f421..d7dfd77 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -1,6 +1,10 @@
#ifndef PLAND_SYSCALL_H
#define PLAND_SYSCALL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <stdint.h>
#include <stdbool.h>
@@ -250,4 +254,8 @@ static inline void _set_file_size(_file_handle_t handle, uint32_t new_size) {
_sc2(_SCN_SET_FILE_SIZE, handle, new_size);
}
+#ifdef __cplusplus
+}
+#endif
+
#endif \ No newline at end of file
diff --git a/src/user/raleigh/runtime.cpp b/src/user/raleigh/runtime.cpp
new file mode 100644
index 0000000..1152575
--- /dev/null
+++ b/src/user/raleigh/runtime.cpp
@@ -0,0 +1,21 @@
+#include <raleigh/runtime.h>
+#include <raleigh/window.h>
+#include <pland/pcrt.h>
+
+namespace raleigh {
+ dllist<window &> open_windows;
+
+ __attribute__ ((noreturn))
+ void start_runtime() {
+ while (1) {
+ if (!open_windows.first)
+ __pcrt_quit();
+ for (dllist<window &>::node *w = open_windows.first; w; w = w->next)
+ if (w->d.try_actions() == window::DELETE)
+ if (!(w = open_windows.remove_in_place(w)))
+ break;
+ _wait_for_action();
+ _yield_task();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/user/raleigh/util.cpp b/src/user/raleigh/util.cpp
new file mode 100644
index 0000000..958897b
--- /dev/null
+++ b/src/user/raleigh/util.cpp
@@ -0,0 +1,6 @@
+#include <raleigh/util.h>
+
+coord::coord(uint32_t x, uint32_t y)
+ : x(x), y(y) {}
+coord::coord()
+ : x(0), y(0) {} \ No newline at end of file
diff --git a/src/user/raleigh/w/label.cpp b/src/user/raleigh/w/label.cpp
new file mode 100644
index 0000000..047126d
--- /dev/null
+++ b/src/user/raleigh/w/label.cpp
@@ -0,0 +1,27 @@
+#include <raleigh/w/label.h>
+#include <libfont/fonts.h>
+#include <knob/block.h>
+
+namespace raleigh {
+ label::label(const char *value, const char *font, _pixel_t bg, _pixel_t fg)
+ : value(value), fi(get_font(font)), bg(bg), fg(fg) {
+ size = coord(
+ fi->space_width * (strlen(value) - 1) + fi->char_width,
+ fi->char_height
+ );
+ }
+
+ void label::notify_window_change() {}
+
+ void label::paint(_pixel_t *pixbuf, uint32_t pitch) {
+ for (uint32_t y = window_offset.y; y < window_offset.y + size.y; ++y)
+ for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x)
+ pixbuf[y * pitch + x] = bg;
+
+ _pixel_t *ptr = pixbuf + window_offset.y * pitch + window_offset.x;
+ for (const char *c = value; *c; ++c) {
+ put_char(fi, *c, ptr, pitch, bg, fg);
+ ptr += fi->space_width;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/user/raleigh/w/padding.cpp b/src/user/raleigh/w/padding.cpp
new file mode 100644
index 0000000..6833c5d
--- /dev/null
+++ b/src/user/raleigh/w/padding.cpp
@@ -0,0 +1,31 @@
+#include <raleigh/w/padding.h>
+
+namespace raleigh {
+ padding::padding(uint32_t pad_by, _pixel_t color, widget &inner)
+ : pad_by(pad_by), color(color), inner(inner) {
+ size = coord(inner.size.x + pad_by * 2, inner.size.y + pad_by * 2);
+ }
+
+ void padding::notify_window_change() {
+ inner.w = w;
+ inner.window_offset = coord(window_offset.x + pad_by, window_offset.y + pad_by);
+ inner.notify_window_change();
+ }
+
+ void padding::paint(_pixel_t *pixbuf, uint32_t pitch) {
+ for (uint32_t y = window_offset.y; y < window_offset.y + pad_by; ++y)
+ for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x)
+ pixbuf[y * pitch + x] = color;
+ for (uint32_t y = window_offset.y + size.y - pad_by; y < window_offset.y + size.y; ++y)
+ for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x)
+ pixbuf[y * pitch + x] = color;
+ for (uint32_t y = window_offset.y + pad_by; y < window_offset.y + size.y - pad_by; ++y) {
+ for (uint32_t x = window_offset.x; x < window_offset.x + pad_by; ++x)
+ pixbuf[y * pitch + x] = color;
+ for (uint32_t x = window_offset.x + size.x - pad_by; x < window_offset.x + size.x; ++x)
+ pixbuf[y * pitch + x] = color;
+ }
+
+ inner.paint(pixbuf, pitch);
+ }
+} \ No newline at end of file
diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp
new file mode 100644
index 0000000..4373b06
--- /dev/null
+++ b/src/user/raleigh/window.cpp
@@ -0,0 +1,35 @@
+#include <raleigh/runtime.h>
+#include <raleigh/window.h>
+#include <knob/heap.h>
+
+namespace raleigh {
+ window::window(widget &root)
+ : size(root.size), root(root) {
+ root.w = this;
+ root.window_offset = coord(0, 0);
+ root.notify_window_change();
+
+ pixbuf = (_pixel_t *)get_block(size.x * size.y * sizeof(_pixel_t));
+
+ root.paint(pixbuf, size.x);
+ handle = _new_window(size.x, size.y, pixbuf);
+
+ open_windows.add_front(*this);
+ }
+
+ window::try_actions_return_t window::try_actions() {
+ struct window_action wa;
+ window::try_actions_return_t got = NONE;
+ while (1) {
+ _get_win_action(handle, &wa);
+ if (!wa.action_type)
+ return got;
+ if ((wa.action_type == wa.KEY_DOWN) &&
+ (wa.as_key.modifiers & wa.as_key.ALTS) &&
+ (wa.as_key.key_id == wa.as_key.KEY_F4))
+ return DELETE;
+ got = GOOD;
+ //TODO
+ }
+ }
+} \ No newline at end of file
diff --git a/src/user/rhello/main.cpp b/src/user/rhello/main.cpp
new file mode 100644
index 0000000..750818c
--- /dev/null
+++ b/src/user/rhello/main.cpp
@@ -0,0 +1,13 @@
+#include <raleigh/w/padding.h>
+#include <raleigh/w/label.h>
+#include <raleigh/runtime.h>
+#include <raleigh/window.h>
+
+using namespace raleigh;
+
+void main() {
+ label l("Hello, world! Close me with Alt+F4.");
+ padding p(4, RGB(bf, bf, bf), l);
+ window w(p);
+ start_runtime();
+} \ No newline at end of file
diff --git a/src/user/runtimes/cxx/extra.asm b/src/user/runtimes/cxx/extra.asm
new file mode 100644
index 0000000..78bb0a8
--- /dev/null
+++ b/src/user/runtimes/cxx/extra.asm
@@ -0,0 +1,7 @@
+bits 32
+
+global __cxa_pure_virtual
+
+section .text
+__cxa_pure_virtual:
+ ret \ No newline at end of file
diff --git a/src/user/runtimes/cxx/extra.ld b/src/user/runtimes/cxx/extra.ld
new file mode 100644
index 0000000..8eddedb
--- /dev/null
+++ b/src/user/runtimes/cxx/extra.ld
@@ -0,0 +1,5 @@
+/* void *operator new(size_t) */
+_Znwj = get_block;
+
+/* void operator delete(void *, size_t) */
+_ZdlPvj = free_block; \ No newline at end of file