summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-18 11:56:08 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-18 11:56:08 -0500
commit00cc8736f10098dedf6b856b9ad8bd0094211263 (patch)
tree4cd252a614b26cb3dcf4a20c142feeffbb4c3c2a /src
parent9d8ce7688f051fc5cd9e917faf3b1e49a3e620ab (diff)
downloadportland-os-00cc8736f10098dedf6b856b9ad8bd0094211263.tar.gz
vbe support, truecolor window manager pixbufs
Diffstat (limited to 'src')
-rw-r--r--src/boot.asm119
-rw-r--r--src/kernel/log.c10
-rw-r--r--src/kernel/main.c28
-rw-r--r--src/kernel/vbe.h71
-rw-r--r--src/kernel/window.c126
-rw-r--r--src/kernel/window.h13
-rw-r--r--src/user/highway/line.c31
-rw-r--r--src/user/highway/main.c1
-rw-r--r--src/user/highway/vars.c44
-rw-r--r--src/user/include/libfont/fonts.h5
-rw-r--r--src/user/include/libterm/command.h4
-rw-r--r--src/user/include/libterm/terminal.h2
-rw-r--r--src/user/include/pland/syscall.h13
-rw-r--r--src/user/include/popups/info.h6
-rw-r--r--src/user/include/popups/popup.h2
-rw-r--r--src/user/libfont/fonts.c3
-rw-r--r--src/user/libterm/terminal.c2
-rw-r--r--src/user/meminfo/meminfo.c3
-rw-r--r--src/user/mkpopup/main.c2
-rw-r--r--src/user/popups/info.c8
-rw-r--r--src/user/terminal/main.c48
21 files changed, 426 insertions, 115 deletions
diff --git a/src/boot.asm b/src/boot.asm
index 08b2834..c19534e 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -8,6 +8,11 @@ support_flags equ 0x4000
pci_hw_char equ 0x4001
pci_ver equ 0x4002
last_pci_bus equ 0x4004
+bios_mmap_len equ 0x4006
+vbe_mode equ 0x4008
+
+vbe_block equ 0x4200
+vbe_mode_info equ 0x4400
pci_support equ 0x80
pae_support equ 0x40
@@ -18,10 +23,7 @@ pae_support equ 0x40
xor ax, ax
mov ss, ax
- mov sp, 0x7ffc
-
- mov ax, 0x0013
- int 0x10
+ mov sp, 0x8000
mov ax, kernel_segment
mov es, ax
@@ -72,7 +74,95 @@ mmap_loop:
test ebx, ebx
jnz mmap_loop
mmap_end:
- mov word [0x4006], di
+ mov word [bios_mmap_len], di
+
+ xor ax, ax
+ mov es, ax
+ mov di, vbe_block
+ mov ah, 0x4f
+
+ mov dword [di], 0x32454256;'VBE2'
+
+ int 0x10
+
+ cmp dword [di], 0x41534556;'VESA'
+ jne no_vbe
+
+ mov bx, word [di + 0x0e]
+ mov ax, word [di + 0x10]
+ mov fs, ax
+ xor esi, esi
+ mov bp, 0xffff
+ mov di, 0x5000
+
+vbe_loop:
+ max_height equ 800
+ ;fs:bx is mode pointer
+ ;esi is highest resolution yet (width * height)
+ ;bp is that mode's number
+ ;uses 0x5000 - 0x50ff as mode info buffer
+ ;skips those without byte-aligned pixels
+
+ mov cx, word [fs:bx]
+ cmp cx, 0xffff
+ je got_highest_vbe
+
+ add bx, 4
+
+ mov ax, 0x4f01
+ int 0x10
+
+ mov al, byte [di]
+
+ test al, 0x01
+ jz vbe_loop
+
+ test al, 0x10
+ jz vbe_loop
+
+ test al, 0x80
+ jz vbe_loop
+
+ mov dx, word [di + 0x14];height
+ cmp dx, max_height
+ jg vbe_loop
+
+ mov ax, word [di + 0x12];width
+ mul dx
+
+ shl edx, 16
+ mov dx, ax
+
+ xor eax, eax
+
+ mov al, byte [di + 0x19];bpp
+ test al, 0x07
+ jnz vbe_loop
+
+ mul edx
+
+ cmp eax, esi
+ jle vbe_loop
+
+ mov esi, eax
+ mov bp, cx
+ jmp vbe_loop
+
+got_highest_vbe:
+ cmp bp, 0xffff
+ je no_vbe
+
+ mov cx, bp
+ mov ax, 0x4f01
+ mov di, vbe_mode_info
+ int 0x10
+
+ or ch, 0x40
+ mov word [vbe_mode], cx
+
+ mov ax, 0x4f02
+ mov bx, cx
+ int 0x10
cli
@@ -84,6 +174,25 @@ mmap_end:
jmp 0x10:pmode
+no_vbe:
+ xor ax, ax
+ mov es, ax
+
+ mov ax, 0x1300
+ mov bx, 0x004f
+ mov cx, no_vbe_str.len
+ xor dx, dx
+ mov bp, no_vbe_str
+ int 0x10
+
+real_halt:
+ hlt
+ jmp real_halt
+
+no_vbe_str:
+ db "NO VBE2!"
+.len equ $ - no_vbe_str
+
bits 32
pmode:
diff --git a/src/kernel/log.c b/src/kernel/log.c
index 6bad1cc..2819a2e 100644
--- a/src/kernel/log.c
+++ b/src/kernel/log.c
@@ -52,8 +52,16 @@ void logf(enum log_level level, const char *format, ...) {
while (*s)
logch(*(s++));
break;
+ case 'n':;
+ uint32_t d = va_arg(args, uint32_t);
+ if (d >= 0x80000000) {
+ logch('-');
+ d = -d;
+ }
+ goto put_dec;
case 'd':;
- const uint32_t d = va_arg(args, uint32_t);
+ d = va_arg(args, uint32_t);
+ put_dec:
if (d == 0) {
logch('0');
break;
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 92315ce..43778d4 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -15,6 +15,7 @@
#include "kbd.h"
#include "log.h"
#include "pci.h"
+#include "vbe.h"
void _start_user_mode() __attribute__ ((noreturn));
@@ -46,12 +47,16 @@ void main() {
logf(LOG_INFO, "Available kernel memory: %dk", kernel_pages_left * 4);
logf(LOG_INFO, "Available user memory: %dk", user_pages_left * 4);
+ logf(LOG_INFO, "");
+
logf(LOG_INFO, "PCI devices:");
for (uint16_t i = 0; i < n_pci_devices; ++i) {
const struct pci_device *dev = nth_pci_device(i);
logf(LOG_INFO, " %hw:%hw (%hb:%hb)", dev->id_vendor, dev->id_device, dev->class, dev->subclass);
}
+ logf(LOG_INFO, "");
+
logf(LOG_INFO, "Drives:");
for (uint8_t i = 0; i < n_drives; ++i) {
const struct drive *d = &drives[i];
@@ -59,6 +64,29 @@ void main() {
logf(LOG_INFO, " %s: %d%sk, %s (%d%sk free)", d->drive_type, d->n_sectors / 2, d->n_sectors % 2 ? ".5" : "", d->fs_type, free / 2, free % 2 ? ".5" : "");
}
+ logf(LOG_INFO, "");
+
+ logf(LOG_INFO, "VBE info:");
+ logf(LOG_INFO, " Implemention: %s", RM_PTR(char, VBE_INFO->oem_name));
+ logf(LOG_INFO, " Video memory: %dk", VBE_INFO->total_memory * 64);
+ logf(LOG_INFO, " Standard: %d.%d.%d", VBE_INFO->major_version, VBE_INFO->minor_version, VBE_INFO->version_rev);
+ logf(LOG_INFO, " Vendor: %s", RM_PTR(char, VBE_INFO->vendor_name));
+ logf(LOG_INFO, " Product: %s", RM_PTR(char, VBE_INFO->product_name));
+ logf(LOG_INFO, " Version: %s", RM_PTR(char, VBE_INFO->product_rev_name));
+
+ logf(LOG_INFO, "");
+
+ #define MASK(offset, length) ((~((1 << offset) - 1)) - (offset + length == 32 ? 0 : (~((1 << (offset + length)) - 1))))
+ logf(LOG_INFO, "Active video mode:");
+ logf(LOG_INFO, " Resolution: %dx%dx%d", VBE_MODE_INFO->width, VBE_MODE_INFO->height, VBE_MODE_INFO->bpp);
+ logf(LOG_INFO, " Red mask: 0x%h", MASK(VBE_MODE_INFO->red_off, VBE_MODE_INFO->red_len));
+ logf(LOG_INFO, " Green mask: 0x%h", MASK(VBE_MODE_INFO->green_off, VBE_MODE_INFO->green_len));
+ logf(LOG_INFO, " Blue mask: 0x%h", MASK(VBE_MODE_INFO->blue_off, VBE_MODE_INFO->blue_len));
+ logf(LOG_INFO, " Alpha mask: 0x%h", MASK(VBE_MODE_INFO->alpha_off, VBE_MODE_INFO->alpha_len));
+ logf(LOG_INFO, " Framebuffer address: 0x%h", VBE_MODE_INFO->frame_buf);
+
+ logf(LOG_INFO, "");
+
logf(LOG_INFO, "Loading init program.");
if (!try_elf_run(drives, "bin/init", "", 0))
diff --git a/src/kernel/vbe.h b/src/kernel/vbe.h
new file mode 100644
index 0000000..6fcdb56
--- /dev/null
+++ b/src/kernel/vbe.h
@@ -0,0 +1,71 @@
+#ifndef VBE_H
+#define VBE_H
+
+#include <stdint.h>
+
+struct segoff {
+ uint16_t offset;
+ uint16_t segment;
+} __attribute__ ((__packed__));
+
+#define RM_PTR(type, segoff) ((type *)((segoff).segment * 16 + (segoff).offset))
+
+enum vbe_capabilities {
+ VBE_CAP_SWITCHABLE_DAC = 0x1,
+ VBE_CAP_NON_VGA = 0x2,
+ VBE_CAP_WEIRD_RAMDAC = 0x4
+};
+
+#define VBE_INFO \
+ ((struct { \
+ uint8_t signature[4]; \
+ uint8_t minor_version; \
+ uint8_t major_version; \
+ struct segoff oem_name; \
+ uint32_t capabilities; \
+ struct segoff mode_list; \
+ /*in units of 64kiB*/ \
+ uint16_t total_memory; \
+ uint16_t version_rev; \
+ struct segoff vendor_name; \
+ struct segoff product_name; \
+ struct segoff product_rev_name; \
+ } __attribute__ ((__packed__)) *)0x4200)
+
+#define VBE_MODE_INFO \
+ ((struct { \
+ uint16_t attribs; \
+ uint8_t wina_attribs; \
+ uint8_t winb_attribs; \
+ uint16_t win_gran; \
+ uint16_t win_size; \
+ uint16_t wina_seg; \
+ uint16_t winb_seg; \
+ struct segoff win_func; \
+ uint16_t pitch;/*in bytes*/ \
+ uint16_t width; \
+ uint16_t height; \
+ uint8_t char_width; \
+ uint8_t char_height; \
+ uint8_t n_planes; \
+ uint8_t bpp; \
+ uint8_t n_banks; \
+ uint8_t mem_model; \
+ uint8_t bank_size;/*in kiB*/\
+ uint8_t image_pages; \
+ uint8_t reserved; \
+ uint8_t red_len; \
+ uint8_t red_off; \
+ uint8_t green_len; \
+ uint8_t green_off; \
+ uint8_t blue_len; \
+ uint8_t blue_off; \
+ uint8_t alpha_len; \
+ uint8_t alpha_off; \
+ uint8_t color_attribs; \
+ void *frame_buf; \
+ void *off_screen; \
+ uint16_t off_screen_length; \
+ } __attribute__ ((__packed__)) *)0x4400)
+
+#endif \ No newline at end of file
diff --git a/src/kernel/window.c b/src/kernel/window.c
index 74273fb..10c573f 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -7,18 +7,21 @@
#include "pmap.h"
#include "elf.h"
#include "log.h"
+#include "vbe.h"
#define MAX_WINDOWS 64
#define ACTION_BUFFER_PAGES 1
#define AB_END(buf) (buf + (ACTION_BUFFER_PAGES * 4096) / sizeof(struct window_action))
-#define BACKGROUND(x, y) ((x / 16 + y / 16) % 2 ? 0x14 : 0x07)
+#define GSC(x, y) (x / 4 + y / 4 >= 256 ? 255 : x / 4 + y / 4)
+#define BACKGROUND(x, y) ((struct pixel){.r = GSC(x / 2, y / 3), .g = GSC(x, y), .b = GSC(x, y / 2)})
-#define BORDER_LIGHT 0x1c
-#define BORDER_DARK 0x08
+#define BORDER_COLOR ((struct pixel){.r = 0x11, .g = 0x11, .b = 0x11})
+
+#define MOVE_BY 5
static struct window {
- const volatile void *pixel_buffer_pma;
+ const volatile struct pixel *pixel_buffer_pma;
uint16_t width;
uint16_t height;
@@ -38,65 +41,74 @@ static struct window {
static struct window *bottom_window = 0;
static struct window *top_window = 0;
-#define SCREEN_HEIGHT 200
-#define SCREEN_WIDTH 320
-#define VGA_MEMORY ((uint8_t *)0xa0000)
+uint32_t pix_clear_mask;
+
+static inline void put_pix(uint16_t y, uint16_t x, struct pixel px) {
+ uint32_t *const fbp = VBE_MODE_INFO->frame_buf + y * VBE_MODE_INFO->pitch + x * VBE_MODE_INFO->bpp / 8;
+//logf(LOG_INFO, "-- fbp = 0x%h", fbp);
+//logf(LOG_INFO, "-- *fbp -> 0x%h", *fbp);
+ *fbp &= pix_clear_mask;
+ *fbp |= (px.r >> (8 - VBE_MODE_INFO->red_len)) << VBE_MODE_INFO->red_off;
+ *fbp |= (px.g >> (8 - VBE_MODE_INFO->green_len)) << VBE_MODE_INFO->green_off;
+ *fbp |= (px.b >> (8 - VBE_MODE_INFO->blue_len)) << VBE_MODE_INFO->blue_off;
+//logf(LOG_INFO, "-- *fbp <- 0x%h", *fbp);
+}
-static inline void draw_hz_line(uint16_t y, uint16_t xs, uint16_t xm, uint8_t color) {
- if (y >= SCREEN_HEIGHT)
+static inline void draw_hz_line(uint16_t y, uint16_t xs, uint16_t xm, struct pixel color) {
+ if (y >= VBE_MODE_INFO->height)
return;
- if (xs >= SCREEN_WIDTH)
+ if (xs >= VBE_MODE_INFO->width)
xs = 0;
- if (xm > SCREEN_WIDTH)
- xm = SCREEN_WIDTH;
- uint8_t *const line_start = VGA_MEMORY + y * SCREEN_WIDTH;
- for (uint8_t *p = line_start + xs; p < line_start + xm; ++p)
- *p = color;
+ if (xm > VBE_MODE_INFO->width)
+ xm = VBE_MODE_INFO->width;
+ for (uint16_t x = xs; x < xm; ++x)
+ put_pix(y, x, color);
}
-static inline void draw_vt_line(uint16_t x, uint16_t ys, uint16_t ym, uint8_t color) {
- if (x >= SCREEN_WIDTH)
+static inline void draw_vt_line(uint16_t x, uint16_t ys, uint16_t ym, struct pixel color) {
+ if (x >= VBE_MODE_INFO->width)
return;
- if (ys >= SCREEN_HEIGHT)
+ if (ys >= VBE_MODE_INFO->height)
ys = 0;
- if (ym > SCREEN_HEIGHT)
- ym = SCREEN_HEIGHT;
- uint8_t *const line_start = VGA_MEMORY + x;
- for (uint8_t *p = line_start + ys * SCREEN_WIDTH; p < line_start + ym * SCREEN_WIDTH; p += SCREEN_WIDTH)
- *p = color;
+ if (ym > VBE_MODE_INFO->height)
+ ym = VBE_MODE_INFO->height;
+ for (uint16_t y = ys; y < ym; ++y)
+ put_pix(y, x, color);
}
static void paint_and_above(const struct window *w) {
switch_to_kernel_cr3();
for (const struct window *i = w; i; i = i->above) {
- const uint16_t ys = i->ypos < SCREEN_HEIGHT ? 0 : -i->ypos;
- const uint16_t xs = i->xpos < SCREEN_WIDTH ? 0 : -i->xpos;
- const uint16_t ym = i->ypos + i->height <= SCREEN_HEIGHT ? i->height : SCREEN_HEIGHT - i->ypos;
- const uint16_t xm = i->xpos + i->width <= SCREEN_WIDTH ? i->width : SCREEN_WIDTH - i->xpos;
+ const uint16_t ys = i->ypos < VBE_MODE_INFO->height ? 0 : -i->ypos;
+ const uint16_t xs = i->xpos < VBE_MODE_INFO->width ? 0 : -i->xpos;
+ const uint16_t ym = ((i->ypos + i->height) & 0xffff) <= VBE_MODE_INFO->height ? i->height : VBE_MODE_INFO->height - i->ypos;
+ const uint16_t xm = ((i->xpos + i->width) & 0xffff) <= VBE_MODE_INFO->width ? i->width : VBE_MODE_INFO->width - i->xpos;
- for (uint16_t y = ys; y < ym; ++y)
- for (uint16_t x = xs; x < xm; ++x) {
- const uint8_t pixel = ((uint8_t *)i->pixel_buffer_pma)[y * i->width + x];
- if (pixel)
- VGA_MEMORY[(y + i->ypos) * SCREEN_WIDTH + x + i->xpos] = pixel;
- }
+ //logf(LOG_INFO, "y: %n .. %n", ys, ym - 1);
+ //logf(LOG_INFO, "x: %n .. %n", xs, xm - 1);
- draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, BORDER_LIGHT);
- draw_vt_line(i->xpos - 2, i->ypos - 1, i->ypos + i->height + 2, BORDER_LIGHT);
- draw_hz_line(i->ypos - 1, i->xpos - 1, i->xpos + i->width + 2, BORDER_DARK);
- draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height + 2, BORDER_DARK);
- draw_hz_line(i->ypos + i->height, i->xpos, i->xpos + i->width + 1, BORDER_LIGHT);
- draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, BORDER_LIGHT);
- draw_hz_line(i->ypos + i->height + 1, i->xpos, i->xpos + i->width + 2, BORDER_DARK);
- draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height + 1, BORDER_DARK);
+ for (uint16_t y = ys; y < ym; ++y)
+ for (uint16_t x = xs; x < xm; ++x)
+ put_pix(y + i->ypos, x + i->xpos, i->pixel_buffer_pma[y * i->width + x]);
+
+ draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos - 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos + i->height, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_hz_line(i->ypos + i->height + 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR);
+ draw_vt_line(i->xpos - 2, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, BORDER_COLOR);
+ draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height, BORDER_COLOR);
}
switch_to_task_cr3();
}
static void paint_bg() {
- for (uint16_t y = 0; y < SCREEN_HEIGHT; ++y)
- for (uint16_t x = 0; x < SCREEN_WIDTH; ++x)
- VGA_MEMORY[y * SCREEN_WIDTH + x] = BACKGROUND(x, y);
+ switch_to_kernel_cr3();
+ for (uint16_t y = 0; y < VBE_MODE_INFO->height; ++y)
+ for (uint16_t x = 0; x < VBE_MODE_INFO->width; ++x)
+ put_pix(y, x, BACKGROUND(x, y));
+ switch_to_task_cr3();
}
static void paint_all() {
@@ -104,7 +116,7 @@ static void paint_all() {
paint_and_above(bottom_window);
}
-struct window *new_window(uint16_t width, uint16_t height, const void *pixel_buffer) {
+struct window *new_window(uint16_t width, uint16_t height, const struct pixel *pixel_buffer) {
if (!pixel_buffer) {
logf(LOG_WARN, "Refusing to create window with null pixel buffer for task %s.", active_task->name);
return 0;
@@ -122,8 +134,8 @@ got_window:
w->pixel_buffer_pma = vma_to_pma(active_task->page_directory, pixel_buffer);
w->width = width;
w->height = height;
- w->xpos = 10;
- w->ypos = 10;
+ w->xpos = (VBE_MODE_INFO->width / 2) - (width / 2);
+ w->ypos = (VBE_MODE_INFO->height / 2) - (height / 2);
struct window_action *const ab = allocate_kernel_pages(ACTION_BUFFER_PAGES);
w->action_buffer = ab;
@@ -174,7 +186,7 @@ void delete_any_windows_from(struct task_state *tstate) {
paint_all();
}
-void resize_window(struct window *w, uint16_t width, uint16_t height, const void *pixel_buffer) {
+void resize_window(struct window *w, uint16_t width, uint16_t height, const struct pixel *pixel_buffer) {
const bool smaller = (width < w->width) || (height < w->height);
w->width = width;
@@ -187,7 +199,7 @@ void resize_window(struct window *w, uint16_t width, uint16_t height, const void
paint_and_above(w);
}
-void reassign_pixel_buffer(struct window *w, const void *pixel_buffer) {
+void reassign_pixel_buffer(struct window *w, const struct pixel *pixel_buffer) {
w->pixel_buffer_pma = vma_to_pma(active_task->page_directory, pixel_buffer);
}
@@ -259,6 +271,14 @@ static char *run_command;
static char *run_command_pass = "";
void init_win() {
+ #define MASK(offset, length) ((~((1 << offset) - 1)) - (offset + length == 32 ? 0 : (~((1 << (offset + length)) - 1))))
+ pix_clear_mask = ~(
+ MASK(VBE_MODE_INFO->red_off, VBE_MODE_INFO->red_len) |
+ MASK(VBE_MODE_INFO->green_off, VBE_MODE_INFO->green_len) |
+ MASK(VBE_MODE_INFO->blue_off, VBE_MODE_INFO->blue_len) |
+ MASK(VBE_MODE_INFO->alpha_off, VBE_MODE_INFO->alpha_len)
+ );
+
paint_bg();
const file_id_t fid = drives->get_file(drives, RUN_COMMAND_FILE);
@@ -323,25 +343,25 @@ void on_action(struct window_action packet) {
break;
case WM_MOVE_LEFT:
if (top_window) {
- --top_window->xpos;
+ top_window->xpos -= MOVE_BY;
paint_all();
}
break;
case WM_MOVE_RIGHT:
if (top_window) {
- ++top_window->xpos;
+ top_window->xpos += MOVE_BY;
paint_all();
}
break;
case WM_MOVE_UP:
if (top_window) {
- --top_window->ypos;
+ top_window->ypos -= MOVE_BY;
paint_all();
}
break;
case WM_MOVE_DOWN:
if (top_window) {
- ++top_window->ypos;
+ top_window->ypos += MOVE_BY;
paint_all();
}
break;
diff --git a/src/kernel/window.h b/src/kernel/window.h
index a226c11..ebd0496 100644
--- a/src/kernel/window.h
+++ b/src/kernel/window.h
@@ -9,13 +9,20 @@
struct window;
+struct pixel {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t pad;
+} __attribute__ ((__packed__));
+
void init_win();
-struct window *new_window(uint16_t width, uint16_t height, const void *pixel_buffer);
+struct window *new_window(uint16_t width, uint16_t height, const struct pixel *pixel_buffer);
void del_window(struct window *w);
-void resize_window(struct window *w, uint16_t width, uint16_t height, const void *pixel_buffer);
-void reassign_pixel_buffer(struct window *w, const void *pixel_buffer);
+void resize_window(struct window *w, uint16_t width, uint16_t height, const struct pixel *pixel_buffer);
+void reassign_pixel_buffer(struct window *w, const struct pixel *pixel_buffer);
void push_window_paint(const struct window *w);
struct window_action next_window_action(struct window *w);
void wait_window_action();
diff --git a/src/user/highway/line.c b/src/user/highway/line.c
index 5d1e543..3bc3bf2 100644
--- a/src/user/highway/line.c
+++ b/src/user/highway/line.c
@@ -12,18 +12,33 @@
#define LINE_SIZE 4096
static char line[LINE_SIZE];
-static inline uint8_t hex_to_int(char ch) {
+static inline uint8_t hex_digit_to_int(char ch) {
return ch - (ch <= '9' ? '0' : 'a' - 10);
}
+static inline uint8_t hex_byte_to_int(const char *ch) {
+ return (hex_digit_to_int(ch[0]) << 4) | hex_digit_to_int(ch[1]);
+}
+
+static inline _pixel_t hex_to_pixel(const char *ch) {
+ return (_pixel_t){
+ .r = hex_byte_to_int(ch),
+ .g = hex_byte_to_int(ch + 2),
+ .b = hex_byte_to_int(ch + 4)
+ };
+}
+
void ensure_color() {
- const struct no_null_sn *color = get_var((struct no_null_sn){.data = "_color", .length = 6});
- //fgbg
- if (color)
- term_set_color(
- (hex_to_int(color->data[0]) << 4) | hex_to_int(color->data[1]),
- (hex_to_int(color->data[2]) << 4) | hex_to_int(color->data[3])
- );
+ const struct no_null_sn *color;
+get_color:
+ color = get_var((struct no_null_sn){.data = "_color", .length = 6});
+ if (color && (color->length == 12))
+ //rgb, fgbg
+ term_set_color(hex_to_pixel(color->data), hex_to_pixel(color->data + 6));
+ else {
+ new_color();
+ goto get_color;
+ }
}
static void line_replace(const char *from) {
diff --git a/src/user/highway/main.c b/src/user/highway/main.c
index 59586c1..47f3985 100644
--- a/src/user/highway/main.c
+++ b/src/user/highway/main.c
@@ -8,7 +8,6 @@
#include "vars.h"
void main(const char *arg) {
- new_color();
source(*arg ? arg : "user/default.rc");
ensure_color();
diff --git a/src/user/highway/vars.c b/src/user/highway/vars.c
index ed9fa3a..2d53c3a 100644
--- a/src/user/highway/vars.c
+++ b/src/user/highway/vars.c
@@ -84,7 +84,7 @@ void dump_vars() {
}
static const char hex_digits[] = "0123456789abcdef";
-static char color[] = {'1', '0', '.', '.'};
+static char color[12] = "000000......";
static const struct no_null_sn color_name = {
.data = "_color",
@@ -93,12 +93,46 @@ static const struct no_null_sn color_name = {
static const struct no_null_sn color_value = {
.data = color,
- .length = 4
+ .length = 12
};
void new_color() {
- const uint8_t bg = gen_rand() % 0x30 + 0x38;
- color[2] = hex_digits[bg >> 4];
- color[3] = hex_digits[bg & 0xf];
+ const uint16_t hue = gen_rand() % (0x33 * 6);
+ _pixel_t bg = {.r = 0xff, .g = 0xcc, .b = 0xcc};
+ if (hue <= 0x33) {
+ bg.b += hue;
+ goto got_bg;
+ }
+ bg.b += 0x33;
+ if (hue <= 0x33 * 2) {
+ bg.r -= hue - 0x33;
+ goto got_bg;
+ }
+ bg.r -= 0x33;
+ if (hue <= 0x33 * 3) {
+ bg.g += hue - 0x33 * 2;
+ goto got_bg;
+ }
+ bg.g += 0x33;
+ if (hue <= 0x33 * 4) {
+ bg.b -= hue - 0x33 * 3;
+ goto got_bg;
+ }
+ bg.b -= 0x33;
+ if (hue <= 0x33 * 5) {
+ bg.r += hue - 0x33 * 4;
+ goto got_bg;
+ }
+ bg.r += 0x33;
+ bg.g -= hue - 0x33 * 5;
+
+got_bg:
+ color[ 6] = hex_digits[bg.r / 16];
+ color[ 7] = hex_digits[bg.r % 16];
+ color[ 8] = hex_digits[bg.g / 16];
+ color[ 9] = hex_digits[bg.g % 16];
+ color[10] = hex_digits[bg.b / 16];
+ color[11] = hex_digits[bg.b % 16];
+
set_var(color_name, color_value);
} \ No newline at end of file
diff --git a/src/user/include/libfont/fonts.h b/src/user/include/libfont/fonts.h
index b66659f..f7ed3e1 100644
--- a/src/user/include/libfont/fonts.h
+++ b/src/user/include/libfont/fonts.h
@@ -1,6 +1,8 @@
#ifndef LIBFONT_FONTS_H
#define LIBFONT_FONTS_H
+#include <pland/syscall.h>
+
#include <stdbool.h>
#include <stdint.h>
@@ -16,6 +18,7 @@ struct font_info {
struct font_info *get_font(const char *name);
-void put_char(const struct font_info *font, char ch, uint8_t *pb_ptr, uint32_t pb_pitch, uint8_t bg, uint8_t fg);
+//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);
#endif \ No newline at end of file
diff --git a/src/user/include/libterm/command.h b/src/user/include/libterm/command.h
index 7587306..ca9e00d 100644
--- a/src/user/include/libterm/command.h
+++ b/src/user/include/libterm/command.h
@@ -37,8 +37,8 @@ struct terminal_command {
uint32_t x;
} as_coords;
struct {
- uint8_t fg;
- uint8_t bg;
+ _pixel_t fg;
+ _pixel_t bg;
} as_color;
char as_char;
uint32_t as_uint;
diff --git a/src/user/include/libterm/terminal.h b/src/user/include/libterm/terminal.h
index 19bd517..40536e0 100644
--- a/src/user/include/libterm/terminal.h
+++ b/src/user/include/libterm/terminal.h
@@ -12,7 +12,7 @@ void term_get_dimensions(uint32_t *width, uint32_t *height);
void term_paint();
void term_clear();
-void term_set_color(uint8_t fg, uint8_t bg);
+void term_set_color(_pixel_t fg, _pixel_t bg);
void term_set_cursor(uint32_t new_y, uint32_t new_x);
void term_cursor_left();
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index fd0b416..9518d09 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -18,6 +18,13 @@ typedef struct __attribute__ ((packed)) {
uint8_t pad[23];
} _dir_info_entry_t;
+typedef struct __attribute__ ((packed)) {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t pad;
+} _pixel_t;
+
enum _scn {
_SCN_OPEN_FILE,
_SCN_CLOSE_FILE,
@@ -177,7 +184,7 @@ static inline uint32_t _count_of_dir(uint8_t drive_number, const char *path) {
return _sc2(_SCN_COUNT_OF_DIR, drive_number, (uint32_t)path);
}
-static inline _window_handle_t _new_window(uint16_t width, uint16_t height, void *pixel_buffer) {
+static inline _window_handle_t _new_window(uint16_t width, uint16_t height, _pixel_t *pixel_buffer) {
return (_window_handle_t)_sc3(_SCN_NEW_WINDOW, width, height, (uint32_t)pixel_buffer);
}
@@ -185,11 +192,11 @@ static inline void _delete_window(_window_handle_t window) {
_sc1(_SCN_DELETE_WINDOW, (uint32_t)window);
}
-static inline void _resize_window(_window_handle_t window, uint16_t width, uint16_t height, const void *pixel_buffer) {
+static inline void _resize_window(_window_handle_t window, uint16_t width, uint16_t height, const _pixel_t *pixel_buffer) {
_sc4(_SCN_RESIZE_WINDOW, (uint32_t)window, width, height, (uint32_t)pixel_buffer);
}
-static inline void _reassign_pixbuf(_window_handle_t window, const void *pixel_buffer) {
+static inline void _reassign_pixbuf(_window_handle_t window, const _pixel_t *pixel_buffer) {
_sc2(_SCN_REASSIGN_PIXBUF, (uint32_t)window, (uint32_t)pixel_buffer);
}
diff --git a/src/user/include/popups/info.h b/src/user/include/popups/info.h
index 2c4e83f..36d557a 100644
--- a/src/user/include/popups/info.h
+++ b/src/user/include/popups/info.h
@@ -7,8 +7,8 @@
#include <stdarg.h>
-void info_popup(struct popup *into, const char *text, uint8_t fg, uint8_t bg);
-void info_popupf(struct popup *into, const char *text, uint8_t fg, uint8_t bg, ...);
-void info_popupf_v(struct popup *into, const char *text, uint8_t fg, uint8_t bg, va_list args);
+void info_popup(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg);
+void info_popupf(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, ...);
+void info_popupf_v(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, va_list args);
#endif \ No newline at end of file
diff --git a/src/user/include/popups/popup.h b/src/user/include/popups/popup.h
index 9a39997..cf4315b 100644
--- a/src/user/include/popups/popup.h
+++ b/src/user/include/popups/popup.h
@@ -5,7 +5,7 @@
struct popup {
_window_handle_t handle;
- uint8_t *pixbuf;
+ _pixel_t *pixbuf;
bool has_quit;
struct key_packet quit_as;
diff --git a/src/user/libfont/fonts.c b/src/user/libfont/fonts.c
index c085604..51e127b 100644
--- a/src/user/libfont/fonts.c
+++ b/src/user/libfont/fonts.c
@@ -56,7 +56,8 @@ struct font_info *get_font(const char *name) {
return 0;
}
-void put_char(const struct font_info *font, char ch, uint8_t *pb_ptr, uint32_t pb_pitch, uint8_t bg, uint8_t fg) {
+//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) {
//char *const msg = format("put_char(font = 0x%x, ch = '%c', pb_ptr = 0x%x, pb_pitch = %u, bg = 0x%2x, fg = 0x%2x);", font, ch, pb_ptr, pb_pitch, bg, fg);
//_system_log(msg);
//free_block(msg);
diff --git a/src/user/libterm/terminal.c b/src/user/libterm/terminal.c
index 387d63f..549194f 100644
--- a/src/user/libterm/terminal.c
+++ b/src/user/libterm/terminal.c
@@ -48,7 +48,7 @@ void term_clear() {
try_send_command(&cmd);
}
-void term_set_color(uint8_t fg, uint8_t bg) {
+void term_set_color(_pixel_t fg, _pixel_t bg) {
struct terminal_command cmd = {
.kind = SET_COLOR,
.as_color = {
diff --git a/src/user/meminfo/meminfo.c b/src/user/meminfo/meminfo.c
index 4dbd6bf..3c3c45b 100644
--- a/src/user/meminfo/meminfo.c
+++ b/src/user/meminfo/meminfo.c
@@ -15,7 +15,8 @@ redo:
"kernel memory free: %uk\n"
"userspace memory free: %uk / %uk\n"
"Escape to quit, F5 to refresh.",
- 0x10, 0x07,
+ (_pixel_t){.r = 0, .g = 0, .b = 0},
+ (_pixel_t){.r = 0xbf, .g = 0xbf, .b = 0xbf},
_kernel_dynamic_area_left() * 4,
_total_userspace_left() * 4,
_total_userspace_size() * 4
diff --git a/src/user/mkpopup/main.c b/src/user/mkpopup/main.c
index 5b56889..05ea4e3 100644
--- a/src/user/mkpopup/main.c
+++ b/src/user/mkpopup/main.c
@@ -31,6 +31,6 @@ void main(const char *text) {
}
struct popup p;
- info_popup(&p, text, 0x10, 0x07);
+ info_popup(&p, text, (_pixel_t){.r = 0, .g = 0, .b = 0}, (_pixel_t){.r = 0xbf, .g = 0xbf, .b = 0xbf});
make_modal(&p);
} \ No newline at end of file
diff --git a/src/user/popups/info.c b/src/user/popups/info.c
index 667d440..eac155b 100644
--- a/src/user/popups/info.c
+++ b/src/user/popups/info.c
@@ -18,7 +18,7 @@ static const struct key_packet info_quits[] = {
{ .key_id = 0 }
};
-void info_popup(struct popup *into, const char *msg, uint8_t fg, uint8_t bg) {
+void info_popup(struct popup *into, const char *msg, _pixel_t fg, _pixel_t bg) {
if (!info_font)
info_font = get_font(FONT);
@@ -41,7 +41,7 @@ void info_popup(struct popup *into, const char *msg, uint8_t fg, uint8_t bg) {
const uint32_t pitch = info_font->space_width * w + 2 * PADDING;
const uint32_t height = info_font->space_height * h + 2 * PADDING;
- uint8_t *const pixbuf = get_block(pitch * height);
+ _pixel_t *const pixbuf = get_block(pitch * height * 4);
for (uint32_t y = 0; y < height; ++y)
for (uint32_t x = 0; x < pitch; ++x)
@@ -63,13 +63,13 @@ void info_popup(struct popup *into, const char *msg, uint8_t fg, uint8_t bg) {
into->handle = _new_window(pitch, height, pixbuf);
}
-void info_popupf_v(struct popup *into, const char *text, uint8_t fg, uint8_t bg, va_list args) {
+void info_popupf_v(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, va_list args) {
char *const msg = format_v(text, args);
info_popup(into, msg, fg, bg);
free_block(msg);
}
-void info_popupf(struct popup *into, const char *text, uint8_t fg, uint8_t bg, ...) {
+void info_popupf(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, ...) {
va_list args;
va_start(args, bg);
info_popupf_v(into, text, fg, bg, args);
diff --git a/src/user/terminal/main.c b/src/user/terminal/main.c
index 3c9eb04..b3e1d9f 100644
--- a/src/user/terminal/main.c
+++ b/src/user/terminal/main.c
@@ -11,22 +11,23 @@
#include <pland/pcrt.h>
#define FONT_HARDCODE "fixed-10"
+#define PADDING 2
_window_handle_t window;
-uint8_t *pixbuf;
+_pixel_t *pixbuf;
char *termbuf;
struct font_info *font;
uint32_t width;
uint32_t height;
-uint32_t cols = 50;
-uint32_t rows = 15;
+uint32_t cols = 100;
+uint32_t rows = 30;
uint32_t cursor_y = 0;
uint32_t cursor_x = 0;
-uint8_t bg_color = 0x10;
-uint8_t fg_color = 0x07;
+_pixel_t bg_color = (_pixel_t){.r = 0, .g = 0, .b = 0};
+_pixel_t fg_color = (_pixel_t){.r = 0xff, .g = 0xff, .b = 0xff};
struct waiting_for_key_record {
_task_handle_t task;
@@ -35,7 +36,7 @@ struct waiting_for_key_record {
static void draw_char(uint32_t y, uint32_t x, bool inverted) {
//syslogf("drawing 0x%2h%s at %u, %u", termbuf[y * cols + x], inverted ? " inverted" : "", y, x);
- put_char(font, termbuf[y * cols + x], pixbuf + y * font->space_height * width + x * font->space_width, width, inverted ? fg_color : bg_color, inverted ? bg_color : fg_color);
+ put_char(font, termbuf[y * cols + x], pixbuf + (y * font->space_height + PADDING) * width + (x * font->space_width + PADDING), width, inverted ? fg_color : bg_color, inverted ? bg_color : fg_color);
}
static void clear() {
@@ -52,9 +53,9 @@ static void scroll_fw() {
for (; i < cols * rows; ++i)
termbuf[i] = ' ';
const uint32_t row_height = font->space_height;
- for (i = 0; i < width * (height - row_height); ++i)
+ for (i = width * PADDING; i < width * (height - PADDING - row_height); ++i)
pixbuf[i] = pixbuf[i + width * row_height];
- for (; i < width * height; ++i)
+ for (; i < width * (height - PADDING); ++i)
pixbuf[i] = bg_color;
}
@@ -187,9 +188,9 @@ static void set_dimensions(uint32_t new_rows, uint32_t new_cols) {
cols = new_cols;
termbuf = get_block(rows * cols);
- width = cols * font->space_width;
- height = cols * font->space_height;
- pixbuf = get_block(width * height);
+ width = cols * font->space_width + PADDING * 2;
+ height = cols * font->space_height + PADDING * 2;
+ pixbuf = get_block(width * height * 4);
cursor_y = 0;
cursor_x = 0;
@@ -199,27 +200,34 @@ static void set_dimensions(uint32_t new_rows, uint32_t new_cols) {
}
void draw_all() {
+ for (uint32_t y = 0; y < PADDING; ++y)
+ for (uint32_t x = 0; x < width; ++x)
+ pixbuf[y * width + x] = bg_color;
+ for (uint32_t y = height - PADDING; y < height; ++y)
+ for (uint32_t x = 0; x < width; ++x)
+ pixbuf[y * width + x] = bg_color;
+ for (uint32_t x = 0; x < PADDING; ++x)
+ for (uint32_t y = PADDING; y < height - PADDING; ++y)
+ pixbuf[y * width + x] = bg_color;
+ for (uint32_t x = width - PADDING; x < width; ++x)
+ for (uint32_t y = PADDING; y < height - PADDING; ++y)
+ pixbuf[y * width + x] = bg_color;
+
for (uint32_t y = 0; y < rows; ++y)
for (uint32_t x = 0; x < cols; ++x)
draw_char(y, x, false);
draw_char(cursor_y, cursor_x, true);
}
-//#include <knob/format.h>
-
void main(const char *cmd) {
-//syslogf(" this task: 0x%2h", this_task);
-//syslogf(" stdio task: 0x%2h", stdio_task);
-//syslogf("calling task: 0x%2h", calling_task);
-
font = get_font(FONT_HARDCODE);
if (!font)
return;
termbuf = get_block(cols * rows);
- width = cols * font->space_width;
- height = rows * font->space_height;
- pixbuf = get_block(width * height);
+ width = cols * font->space_width + PADDING * 2;
+ height = rows * font->space_height + PADDING * 2;
+ pixbuf = get_block(width * height * 4);
clear();
add_sz_ww("Portland Terminal\n");
window = _new_window(width, height, pixbuf);