From 406af09ade55553e2b064506c3ba3c89bd965d73 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Thu, 4 Mar 2021 19:11:42 -0500 Subject: start of a c++ widget toolkit, c++ runtime --- src/shared/include/winact.h | 15 ++++++------ src/user/include/cxx/raleigh/runtime.h | 12 ++++++++++ src/user/include/cxx/raleigh/util.h | 15 ++++++++++++ src/user/include/cxx/raleigh/w/label.h | 24 ++++++++++++++++++++ src/user/include/cxx/raleigh/w/padding.h | 20 ++++++++++++++++ src/user/include/cxx/raleigh/widget.h | 27 ++++++++++++++++++++++ src/user/include/cxx/raleigh/window.h | 27 ++++++++++++++++++++++ src/user/include/cxx/structs/dllist.h | 39 ++++++++++++++++++++++++++++++++ src/user/include/knob/block.h | 8 +++++++ src/user/include/knob/heap.h | 8 +++++++ src/user/include/libfont/fonts.h | 8 +++++++ src/user/include/pland/pcrt.h | 8 +++++++ src/user/include/pland/syscall.h | 8 +++++++ src/user/raleigh/runtime.cpp | 21 +++++++++++++++++ src/user/raleigh/util.cpp | 6 +++++ src/user/raleigh/w/label.cpp | 27 ++++++++++++++++++++++ src/user/raleigh/w/padding.cpp | 31 +++++++++++++++++++++++++ src/user/raleigh/window.cpp | 35 ++++++++++++++++++++++++++++ src/user/rhello/main.cpp | 13 +++++++++++ src/user/runtimes/cxx/extra.asm | 7 ++++++ src/user/runtimes/cxx/extra.ld | 5 ++++ 21 files changed, 356 insertions(+), 8 deletions(-) create mode 100644 src/user/include/cxx/raleigh/runtime.h create mode 100644 src/user/include/cxx/raleigh/util.h create mode 100644 src/user/include/cxx/raleigh/w/label.h create mode 100644 src/user/include/cxx/raleigh/w/padding.h create mode 100644 src/user/include/cxx/raleigh/widget.h create mode 100644 src/user/include/cxx/raleigh/window.h create mode 100644 src/user/include/cxx/structs/dllist.h create mode 100644 src/user/raleigh/runtime.cpp create mode 100644 src/user/raleigh/util.cpp create mode 100644 src/user/raleigh/w/label.cpp create mode 100644 src/user/raleigh/w/padding.cpp create mode 100644 src/user/raleigh/window.cpp create mode 100644 src/user/rhello/main.cpp create mode 100644 src/user/runtimes/cxx/extra.asm create mode 100644 src/user/runtimes/cxx/extra.ld (limited to 'src') 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 +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 +#include + +namespace raleigh { + void start_runtime() __attribute__ ((noreturn)); + extern dllist 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 + +#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 +#include + +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 + +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 +#include +#include + +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 +#include +#include + +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 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 #include @@ -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 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 #include @@ -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 #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 #include @@ -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 +#include +#include + +namespace raleigh { + dllist open_windows; + + __attribute__ ((noreturn)) + void start_runtime() { + while (1) { + if (!open_windows.first) + __pcrt_quit(); + for (dllist::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 + +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 +#include +#include + +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 + +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 +#include +#include + +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 +#include +#include +#include + +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 -- cgit v1.2.3