diff --git a/brewos.iso b/brewos.iso index b809bed..4ed9645 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/src/kernel/cli_apps_old/beep.h b/src/kernel/cli_apps_old/beep.h deleted file mode 100644 index 81aeaa8..0000000 --- a/src/kernel/cli_apps_old/beep.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef BEEP_H -#define BEEP_H - -#include "../print.h" -#include "../io.h" - -// Forward declaration of brewing function from main.c -void brewing(int iterations); - -void beep_command() { - brew_str("\n"); - brew_str("BEEP!"); - // Add a 500ms delay before the beep - brewing(5000000); - - // Set the PIT to the desired frequency (1000 Hz for high pitch) - outb(0x43, 0xB6); // Command byte: channel 2, mode 3, binary - int frequency = 1000; - int divisor = 1193180 / frequency; - outb(0x42, divisor & 0xFF); - outb(0x42, (divisor >> 8) & 0xFF); - - // Turn speaker on - outb(0x61, inb(0x61) | 0x03); - - // Keep the sound for 1 second - brewing(10000000); - - // Turn speaker off - outb(0x61, inb(0x61) & 0xFC); - - brewing(1000000); - - outb(0x61, inb(0x61) | 0x03); - - // Keep the sound for 1 second - brewing(50000000); - - // Turn speaker off - outb(0x61, inb(0x61) & 0xFC); - - // Turn speaker on - outb(0x61, inb(0x61) | 0x03); - - // Keep the sound for 1 second - brewing(10000000); - - // Turn speaker off - outb(0x61, inb(0x61) & 0xFC); - - brewing(1000000); - - outb(0x61, inb(0x61) | 0x03); - - // Keep the sound for 1 second - brewing(50000000); - - // Turn speaker off - outb(0x61, inb(0x61) & 0xFC); - - -} - -#endif \ No newline at end of file diff --git a/src/kernel/cli_apps_old/blind.h b/src/kernel/cli_apps_old/blind.h deleted file mode 100644 index 34f67aa..0000000 --- a/src/kernel/cli_apps_old/blind.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_BLIND_H -#define APPS_BLIND_H - -#include "print.h" - -static void blindme() { - print_set_color(PRINT_INDEX_0, PRINT_INDEX_15); - print_clear(); - brew_str("Woah.. is this heaven?\n"); - brew_str("no.\n"); - brew_str("This isn't TempleOS you fucking retard.\n"); - - -} - -#endif // APPS_BLIND_H diff --git a/src/kernel/cli_apps_old/calc.h b/src/kernel/cli_apps_old/calc.h deleted file mode 100644 index 3fbd9dc..0000000 --- a/src/kernel/cli_apps_old/calc.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_CALC_H -#define APPS_CALC_H - -#include "print.h" -#include "keyboard.h" - -extern int buffer_pos; - -// Calculator state structure -struct { - char display[64]; // Display buffer for calculation - int display_len; - long current_val; - long prev_val; - char operation; - int cursor_row; // 0-3 for numpad rows - int cursor_col; // 0-3 for numpad cols - int has_operation; -} calc_state; - -// Redraw the calculator UI -static void calc_redraw_ui() { - // Clear screen by printing newlines (but fewer to avoid deadspace) - for (int i = 0; i < 24; i++) { - brew_str("\n"); - } - - // Display header - brew_str("===== CALCULATOR =====\n"); - brew_str("Display: "); - brew_str(calc_state.display); - brew_str("\n\n"); - - // Draw numpad with cursor - const char* buttons[4][4] = { - {"7", "8", "9", "/"}, - {"4", "5", "6", "*"}, - {"1", "2", "3", "-"}, - {"0", ".", "=", "+"} - }; - - for (int row = 0; row < 4; row++) { - brew_str(" "); - for (int col = 0; col < 4; col++) { - if (row == calc_state.cursor_row && col == calc_state.cursor_col) { - brew_str("["); - brew_str(buttons[row][col]); - brew_str("]"); - } else { - brew_str(" "); - brew_str(buttons[row][col]); - brew_str(" "); - } - brew_str(" "); - } - brew_str("\n"); - } - - brew_str("\nNavigate: Arrow Keys | Select: Enter | Clear: C | Quit: Q/ESC\n"); -} - -// Get button at current cursor position -static const char* calc_get_button() { - const char* buttons[4][4] = { - {"7", "8", "9", "/"}, - {"4", "5", "6", "*"}, - {"1", "2", "3", "-"}, - {"0", ".", "=", "+"} - }; - return buttons[calc_state.cursor_row][calc_state.cursor_col]; -} - -// Append character to display -static void calc_append_to_display(const char* text) { - int i = 0; - while (text[i] && calc_state.display_len < 63) { - calc_state.display[calc_state.display_len++] = text[i++]; - } - calc_state.display[calc_state.display_len] = '\0'; -} - -// Parse and calculate result -static void calc_perform_calculation() { - if (calc_state.display_len == 0) return; - - // Parse the current display value - long val = 0; - int i = 0; - int is_negative = 0; - - if (calc_state.display[0] == '-') { - is_negative = 1; - i = 1; - } - - while (i < calc_state.display_len && calc_state.display[i] != '.') { - if (calc_state.display[i] >= '0' && calc_state.display[i] <= '9') { - val = val * 10 + (calc_state.display[i] - '0'); - } - i++; - } - - if (is_negative) val = -val; - - long result = val; - - if (calc_state.has_operation) { - switch (calc_state.operation) { - case '+': result = calc_state.prev_val + val; break; - case '-': result = calc_state.prev_val - val; break; - case '*': result = calc_state.prev_val * val; break; - case '/': - if (val != 0) result = calc_state.prev_val / val; - else { - calc_state.display_len = 0; - calc_append_to_display("ERROR"); - return; - } - break; - } - } - - // Convert result back to string - calc_state.display_len = 0; - if (result < 0) { - calc_append_to_display("-"); - result = -result; - } - - if (result == 0) { - calc_append_to_display("0"); - } else { - char temp[32]; - int len = 0; - long temp_val = result; - while (temp_val > 0) { - temp[len++] = '0' + (temp_val % 10); - temp_val /= 10; - } - - // Reverse and append - for (int j = len - 1; j >= 0; j--) { - char c[2] = {temp[j], '\0'}; - calc_append_to_display(c); - } - } - - calc_state.prev_val = result; -} - -// Main calculator command -static void calc_cmd() { - // Initialize calculator state - calc_state.display[0] = '\0'; - calc_state.display_len = 0; - calc_state.current_val = 0; - calc_state.prev_val = 0; - calc_state.operation = '\0'; - calc_state.cursor_row = 0; - calc_state.cursor_col = 0; - calc_state.has_operation = 0; - - calc_redraw_ui(); - - buffer_pos = 0; - - while (1) { - if (check_keyboard()) { - unsigned char scan_code = read_scan_code(); - - // Handle arrow keys for navigation - if (scan_code == 0x48) { // UP arrow - if (calc_state.cursor_row > 0) { - calc_state.cursor_row--; - calc_redraw_ui(); - } - continue; - } else if (scan_code == 0x50) { // DOWN arrow - if (calc_state.cursor_row < 3) { - calc_state.cursor_row++; - calc_redraw_ui(); - } - continue; - } else if (scan_code == 0x4B) { // LEFT arrow - if (calc_state.cursor_col > 0) { - calc_state.cursor_col--; - calc_redraw_ui(); - } - continue; - } else if (scan_code == 0x4D) { // RIGHT arrow - if (calc_state.cursor_col < 3) { - calc_state.cursor_col++; - calc_redraw_ui(); - } - continue; - } - - char ascii_char = scan_code_to_ascii(scan_code); - - // Handle C key to clear - if (ascii_char == 'c' || ascii_char == 'C') { - calc_state.display[0] = '\0'; - calc_state.display_len = 0; - calc_state.current_val = 0; - calc_state.prev_val = 0; - calc_state.operation = '\0'; - calc_state.has_operation = 0; - calc_redraw_ui(); - continue; - } - - // Handle Q key or ESC to quit - if (ascii_char == 'q' || ascii_char == 'Q' || scan_code == 0x01) { - brew_str("\n"); - return; - } - - // Handle Enter to select button - if (ascii_char == '\n' || scan_code == 0x1C) { - const char* button = calc_get_button(); - - if (button[0] >= '0' && button[0] <= '9') { - // Number button - calc_append_to_display(button); - calc_redraw_ui(); - } else if (button[0] == '.') { - // Decimal point - int has_dot = 0; - for (int i = 0; i < calc_state.display_len; i++) { - if (calc_state.display[i] == '.') { - has_dot = 1; - break; - } - } - if (!has_dot && calc_state.display_len > 0) { - calc_append_to_display("."); - calc_redraw_ui(); - } - } else if (button[0] == '=' || button[0] == '+' || - button[0] == '-' || button[0] == '*' || button[0] == '/') { - - if (button[0] == '=') { - if (calc_state.has_operation && calc_state.display_len > 0) { - calc_perform_calculation(); - calc_state.operation = '\0'; - calc_state.has_operation = 0; - calc_redraw_ui(); - } - } else { - // Operation button pressed - if (calc_state.display_len > 0) { - // If we already have an operation pending, calculate first - if (calc_state.has_operation) { - calc_perform_calculation(); - } else { - // First operation: save display value to prev_val - calc_perform_calculation(); - } - // Set new operation - calc_state.operation = button[0]; - calc_state.has_operation = 1; - calc_state.display_len = 0; - calc_state.display[0] = '\0'; - calc_redraw_ui(); - } - } - continue; - } - } - } - } -} - -#endif // APPS_CALC_H \ No newline at end of file diff --git a/src/kernel/cli_apps_old/cowsay.h b/src/kernel/cli_apps_old/cowsay.h deleted file mode 100644 index ccc77f5..0000000 --- a/src/kernel/cli_apps_old/cowsay.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Brew Kernel Cowsay Utility - * Copyright (C) 2024-2026 boreddevnl - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -// -// Implementation of cowsay from GNU/LINUX for Brew Kernel. -// Props to Tony Monroe for the original concept. -// One of these days we WONT port it to Windows. :3 -// -#ifndef APPS_COWSAY_H -#define APPS_COWSAY_H - -#include "print.h" - -// Function to calculate string length since we don't have string.h -static int brew_strlen(const char* str) { - int len = 0; - while (str[len]) len++; - return len; -} - -// String comparison for parsing command -static int strncmp_kernel(const char* s1, const char* s2, int n) { - while (n-- > 0) { - if (*s1 != *s2) { - return (*s1 - *s2); - } - if (*s1 == '\0') { - return 0; - } - s1++; - s2++; - } - return 0; -} - -// Function to find where the command arguments start -static const char* find_args(const char* cmd) { - while (*cmd && *cmd != ' ') cmd++; - while (*cmd == ' ') cmd++; - return cmd; -} - -// Function to draw the top border of the speech bubble -static void draw_top_border(int width) { - brew_str(" "); - for (int i = 0; i < width + 2; i++) { - brew_str("_"); - } - brew_str("\n"); -} - -// Function to draw the bottom border of the speech bubble -static void draw_bottom_border(int width) { - brew_str(" "); - for (int i = 0; i < width + 2; i++) { - brew_str("-"); - } - brew_str("\n"); -} - -// Main cowsay function -static void cowsay(const char* message) { - int len = brew_strlen(message); - - // Draw speech bubble - brew_str("\n"); // Start with a newline for better spacing - draw_top_border(len); - brew_str("< "); - brew_str(message); - brew_str(" >\n"); - draw_bottom_border(len); - - // Draw the cow - brew_str(" \\ ^__^\n"); - brew_str(" \\ (oo)\\_______\n"); - brew_str(" (__)\\ )\\/\\\n"); - brew_str(" ||----w |\n"); - brew_str(" || ||\n\n"); -} - -// Entry point for the cowsay command -static void display_cowsay(const char* command) { - const char* message; - if (!command || brew_strlen(command) == 0) { - message = "Brew!"; - } else { - message = find_args(command); - if (brew_strlen(message) == 0) { - message = "Brew!"; - } - } - cowsay(message); -} -#endif // APPS_COWSAY_H diff --git a/src/kernel/cli_apps_old/date.h b/src/kernel/cli_apps_old/date.h deleted file mode 100644 index 417278c..0000000 --- a/src/kernel/cli_apps_old/date.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef DATE_H -#define DATE_H - -#include "print.h" -#include "keyboard.h" -#include "rtc.h" -#include "timezones.h" - -// String comparison function for kernel -static int strcmp_kernel_date(const char *s1, const char *s2) { - while (*s1 && (*s1 == *s2)) { - s1++; - s2++; - } - return *(const unsigned char*)s1 - *(const unsigned char*)s2; -} - -// Simple delay function -static inline void brewing_date(int iterations) { - for (volatile int i = 0; i < iterations; i++) { - __asm__ __volatile__("nop"); - } -} - -// --- Timezone Selection --- -static void select_timezone_for_continent_date(const char* continent, int* timezone_offset_h, int* timezone_offset_m) { - int selected_timezone = 0; - int needs_redraw = 1; - - while (1) { - if (needs_redraw) { - print_clear(); - brew_str("Select a timezone:\n"); - int current_timezone = 0; - for (int i = 0; i < num_timezones; i++) { - if (strcmp_kernel_date(timezones[i].continent, continent) == 0) { - if (current_timezone == selected_timezone) { - print_set_color(PRINT_INDEX_0, PRINT_INDEX_7); - } - brew_str(timezones[i].name); - brew_str("\n"); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - current_timezone++; - } - } - needs_redraw = 0; - } - - while (!check_keyboard()) { /* Do nothing */ } - - unsigned char sc = read_scan_code(); - if (sc == 0x48) { // Up Arrow - if (selected_timezone > 0) { - selected_timezone--; - needs_redraw = 1; - } - } else if (sc == 0x50) { // Down Arrow - int max_timezone = 0; - for (int i = 0; i < num_timezones; i++) { - if (strcmp_kernel_date(timezones[i].continent, continent) == 0) { - max_timezone++; - } - } - if (selected_timezone < max_timezone - 1) { - selected_timezone++; - needs_redraw = 1; - } - } else if (scan_code_to_ascii(sc) == '\n' || scan_code_to_ascii(sc) == '\r') { - int current_timezone = 0; - for (int i = 0; i < num_timezones; i++) { - if (strcmp_kernel_date(timezones[i].continent, continent) == 0) { - if (current_timezone == selected_timezone) { - *timezone_offset_h = timezones[i].offset_h; // DST - *timezone_offset_m = timezones[i].offset_m; - return; - } - current_timezone++; - } - } - } - brewing_date(10000000); - } -} - -static void select_continent_date(int* timezone_offset_h, int* timezone_offset_m) { - const char* continents[] = {"North America", "South America", "Europe", "Asia", "Oceania", "Africa"}; - int num_continents = sizeof(continents) / sizeof(char*); - int selected_continent = 0; - int needs_redraw = 1; - - while (1) { - if (needs_redraw) { - print_clear(); - brew_str("Select a continent:\n"); - for (int i = 0; i < num_continents; i++) { - if (i == selected_continent) { - print_set_color(PRINT_INDEX_0, PRINT_INDEX_7); - } - brew_str(continents[i]); - brew_str("\n"); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - } - needs_redraw = 0; - } - - while (!check_keyboard()) { /* Do nothing */ } - - unsigned char sc = read_scan_code(); - if (sc == 0x48) { // Up Arrow - if (selected_continent > 0) { - selected_continent--; - needs_redraw = 1; - } - } else if (sc == 0x50) { // Down Arrow - if (selected_continent < num_continents - 1) { - selected_continent++; - needs_redraw = 1; - } - } else if (scan_code_to_ascii(sc) == '\n' || scan_code_to_ascii(sc) == '\r') { - select_timezone_for_continent_date(continents[selected_continent], timezone_offset_h, timezone_offset_m); - return; - } - brewing_date(10000000); - } -} - -// Function to print a zero-padded integer -static void brew_int_padded_date(int n) { - if (n >= 0 && n < 10) { - print_char('0'); - } - brew_int(n); -} - -static void date_command(int* timezone_offset_h, int* timezone_offset_m) { - select_continent_date(timezone_offset_h, timezone_offset_m); - int year, month, day, hour, minute, second; - get_datetime(&year, &month, &day, &hour, &minute, &second); - - // Apply timezone offset - hour += *timezone_offset_h; - minute += *timezone_offset_m; - - // Handle minute overflow/underflow - if (minute >= 60) { - hour++; - minute -= 60; - } else if (minute < 0) { - hour--; - minute += 60; - } - - // Handle hour overflow/underflow - if (hour >= 24) { - day++; - hour -= 24; - } else if (hour < 0) { - day--; - hour += 24; - } - - // Note: This doesn't handle day/month/year wrapping correctly. It's a simplified implementation. - - brew_str("\nCurrent Date and Time:\n"); - brew_int(year); - brew_str("-"); - brew_int_padded_date(month); - brew_str("-"); - brew_int_padded_date(day); - brew_str(" "); - brew_int_padded_date(hour); - brew_str(":"); - brew_int_padded_date(minute); - brew_str(":"); - brew_int_padded_date(second); - brew_str("\n"); -} - -#endif // DATE_H diff --git a/src/kernel/cli_apps_old/help.h b/src/kernel/cli_apps_old/help.h deleted file mode 100644 index 8ff6b7a..0000000 --- a/src/kernel/cli_apps_old/help.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_HELP_H -#define APPS_HELP_H - -#include "../print.h" - -static void display_help() { - brew_str("\nAvailable commands:\n"); - brew_str(" HELP - Display this help message\n"); - brew_str(" DATE - Display the current date and time\n"); - brew_str(" EXIT - Exit CLI mode and return to regular typing\n"); - brew_str(" CLEAR - Clear the screen\n"); - brew_str(" ABOUT - Display system information\n"); - brew_str(" MATH - Perform basic arithmetic\n"); - brew_str(" MAN - Show the detailed user manual\n"); - brew_str(" LICENSE - Display the GNU GPLv3 license\n"); - brew_str(" UPTIME - Show how long the system has been running\n"); - brew_str(" MEMORY - Display memory usage statistics\n"); - brew_str(" BEEP - Makes a beep sound using the PC speaker\n"); - brew_str(" TXTEDIT - Open the text editor\n"); - brew_str(" COWSAY. - MOO!\n"); - brew_str(" LS - List files in current directory\n"); - brew_str(" CD - Change current directory\n"); - brew_str(" PWD - Print working directory\n"); - brew_str(" MKDIR - Create one or more directories\n"); - brew_str(" RM - Remove a file or empty directory\n"); - brew_str(" CAT - Display file contents\n"); - brew_str(" TOUCH - Create an empty file\n"); - brew_str(" ECHO - Print text (can redirect to file with >)\n"); - brew_str(" NETINIT - Initialize network card\n"); - brew_str(" NETINFO - Show network status (MAC, IP)\n"); - brew_str(" UDPTEST - Start UDP echo server on port 12345 (broken)\n"); - brew_str(" UDPSEND - Send UDP packet (UDPSEND )\n"); - brew_str("\nPipe support:\n"); - brew_str(" CAT | UDPSEND - Send file contents via UDP\n"); -} - -#endif // APPS_HELP_H diff --git a/src/kernel/cli_apps_old/license.h b/src/kernel/cli_apps_old/license.h deleted file mode 100644 index 170f195..0000000 --- a/src/kernel/cli_apps_old/license.h +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_LICENSE_H -#define APPS_LICENSE_H - -#include "print.h" -#include "keyboard.h" - -const char* license_pages[] = { - " GNU GENERAL PUBLIC LICENSE", - " Version 3, 29 June 2007", - " Copyright (C) 2024-2026 boreddevnl", - "", - " ", - " Copyright (C) 2007 Free Software Foundation, Inc. ", - " Everyone is permitted to copy and distribute verbatim copies", - " of this license document, but changing it is not allowed.", - "", - " Preamble", - "", - " The GNU General Public License is a free, copyleft license for", - "software and other kinds of works.", - "", - " The licenses for most software and other practical works are designed", - "to take away your freedom to share and change the works. By contrast,", - "the GNU General Public License is intended to guarantee your freedom to", - "share and change all versions of a program--to make sure it remains free", - "software for all its users. We, the Free Software Foundation, use the", - "GNU General Public License for most of our software; it applies also to", - "any other work released this way by its authors. You can apply it to", - "your programs, too.", - "", - " When we speak of free software, we are referring to freedom, not", - "price. Our General Public Licenses are designed to make sure that you", - "have the freedom to distribute copies of free software (and charge for", - "them if you wish), that you receive source code or can get it if you", - "want it, that you can change the software or use pieces of it in new", - "free programs, and that you know you can do these things.", - "", - " To protect your rights, we need to prevent others from denying you", - "these rights or asking you to surrender the rights. Therefore, you have", - "certain responsibilities if you distribute copies of the software, or if", - "you modify it: responsibilities to respect the freedom of others.", - "", - " For example, if you distribute copies of such a program, whether", - "gratis or for a fee, you must pass on to the recipients the same", - "freedoms that you received. You must make sure that they, too, receive", - "or can get the source code. And you must show them these terms so they", - "know their rights.", - "", - " Developers that use the GNU GPL protect your rights with two steps:", - "(1) assert copyright on the software, and (2) offer you this License", - "giving you legal permission to copy, distribute and/or modify it.", - "", - " For the developers' and authors' protection, the GPL clearly explains", - "that there is no warranty for this free software. For both users' and", - "authors' sake, the GPL requires that modified versions be marked as", - "changed, so that their problems will not be attributed erroneously to", - "authors of previous versions.", - "", - " Some devices are designed to deny users access to install or run", - "modified versions of the software inside them, although the manufacturer", - "can do so. This is fundamentally incompatible with the aim of", - "protecting users' freedom to change the software. The systematic", - "pattern of such abuse occurs in the area of products for individuals to", - "use, which is precisely where it is most unacceptable. Therefore, we", - "have designed this version of the GPL to prohibit the practice for those", - "products. If such problems arise substantially in other domains, we", - "stand ready to extend this provision to those domains in future versions", - "of the GPL, as needed to protect the freedom of users.", - "", - " Finally, every program is threatened constantly by software patents.", - "States should not allow patents to restrict development and use of", - "software on general-purpose computers, but in those that do, we wish to", - "avoid the special danger that patents applied to a free program could", - "make it effectively proprietary. To prevent this, the GPL assures that", - "patents cannot be used to render the program non-free.", - "", - " The precise terms and conditions for copying, distribution and", - "modification follow.", - "", - " TERMS AND CONDITIONS", - "", - " 0. Definitions.", - "", - " 'This License' refers to version 3 of the GNU General Public License.", - "", - " 'Copyright' also means copyright-like laws that apply to other kinds of", - "works, such as semiconductor masks.", - "", - " 'The Program' refers to any copyrightable work licensed under this", - "License. Each licensee is addressed as 'you'. 'Licensees' and", - "'recipients' may be individuals or organizations.", - "", - " To 'modify' a work means to copy from or adapt all or part of the work", - "in a fashion requiring copyright permission, other than the making of an", - "exact copy. The resulting work is called a 'modified version' of the", - "earlier work or a work 'based on' the earlier work.", - "", - " A 'covered work' means either the unmodified Program or a work based", - "on the Program.", - "", - " To 'propagate' a work means to do anything with it that, without", - "permission, would make you directly or secondarily liable for", - "infringement under applicable copyright law, except executing it on a", - "computer or modifying a private copy. Propagation includes copying,", - "distribution (with or without modification), making available to the", - "public, and in some countries other activities as well.", - "", - " To 'convey' a work means any kind of propagation that enables other", - "parties to make or receive copies. Mere interaction with a user through", - "a computer network, with no transfer of a copy, is not conveying.", - "", - " An interactive user interface displays 'Appropriate Legal Notices'", - "to the extent that it includes a convenient and prominently visible", - "feature that (1) displays an appropriate copyright notice, and (2)", - "tells the user that there is no warranty for the work (except to the", - "extent that warranties are provided), that licensees may convey the", - "work under this License, and how to view a copy of this License. If", - "the interface presents a list of user commands or options, such as a", - "menu, a prominent item in the list meets this criterion.", - "", - " 1. Source Code.", - "", - " The 'source code' for a work means the preferred form of the work", - "for making modifications to it. 'Object code' means any non-source", - "form of a work.", - "", - " A 'Standard Interface' means an interface that either is an official", - "standard defined by a recognized standards body, or, in the case of", - "interfaces specified for a particular programming language, one that", - "is widely used among developers working in that language.", - "", - " The 'System Libraries' of an executable work include anything, other", - "than the work as a whole, that (a) is included in the normal form of", - "packaging a Major Component, but which is not part of that Major", - "Component, and (b) serves only to enable use of the work with that", - "Major Component, or to implement a Standard Interface for which an", - "implementation is available to the public in source code form. A", - "'Major Component', in this context, means a major essential component", - "(kernel, window system, and so on) of the specific operating system", - "(if any) on which the executable work runs, or a compiler used to", - "produce the work, or an object code interpreter used to run it.", - "", - " The 'Corresponding Source' for a work in object code form means all", - "the source code needed to generate, install, and (for an executable", - "work) run the object code and to modify the work, including scripts to", - "control those activities. However, it does not include the work's", - "System Libraries, or general-purpose tools or generally available free", - "programs which are used unmodified in performing those activities but", - "which are not part of the work. For example, Corresponding Source", - "includes interface definition files associated with source files for", - "the work, and the source code for shared libraries and dynamically", - "linked subprograms that the work is specifically designed to require,", - "such as by intimate data communication or control flow between those", - "subprograms and other parts of the work.", - "", - " The Corresponding Source need not include anything that users", - "can regenerate automatically from other parts of the Corresponding", - "Source.", - "", - " The Corresponding Source for a work in source code form is that", - "same work.", - "", - " 2. Basic Permissions.", - "", - " All rights granted under this License are granted for the term of", - "copyright on the Program, and are irrevocable provided the stated", - "conditions are met. This License explicitly affirms your unlimited", - "permission to run the unmodified Program. The output from running a", - "covered work is covered by this License only if the output, given its", - "content, constitutes a covered work. This License acknowledges your", - "rights of fair use or other equivalent, as provided by copyright law.", - "", - " You may make, run and propagate covered works that you do not", - "convey, without conditions so long as your license otherwise remains", - "in force. You may convey covered works to others for the sole purpose", - "of having them make modifications exclusively for you, or provide you", - "with facilities for running those works, provided that you comply with", - "the terms of this License in conveying all material for which you do", - "not control copyright. Those thus making or running the covered works", - "for you must do so exclusively on your behalf, under your direction", - "and control, on terms that prohibit them from making any copies of", - "your copyrighted material outside their relationship with you.", - "", - " Conveying under any other circumstances is permitted solely under", - "the conditions stated below. Sublicensing is not allowed; section 10", - "makes it unnecessary.", - "", - " 3. Protecting Users' Legal Rights From Anti-Circumvention Law.", - "", - " No covered work shall be deemed part of an effective technological", - "measure under any applicable law fulfilling obligations under article", - "11 of the WIPO copyright treaty adopted on 20 December 1996, or", - "similar laws prohibiting or restricting circumvention of such", - "measures.", - "", - " When you convey a covered work, you waive any legal power to forbid", - "circumvention of technological measures to the extent such circumvention", - "is effected by exercising rights under this License with respect to", - "the covered work, and you disclaim any intention to limit operation or", - "modification of the work as a means of enforcing, against the work's", - "users, your or third parties' legal rights to forbid circumvention of", - "technological measures.", - "", - " 4. Conveying Verbatim Copies.", - "", - " You may convey verbatim copies of the Program's source code as you", - "receive it, in any medium, provided that you conspicuously and", - "appropriately publish on each copy an appropriate copyright notice;", - "keep intact all notices stating that this License and any", - "non-permissive terms added in accord with section 7 apply to the code;", - "keep intact all notices of the absence of any warranty; and give all", - "recipients a copy of this License along with the Program.", - "", - " You may charge any price or no price for each copy that you convey,", - "and you may offer support or warranty protection for a fee.", - "", - " 5. Conveying Modified Source Versions.", - "", - " You may convey a work based on the Program, or the modifications to", - "produce it from the Program, in the form of source code under the", - "terms of section 4, provided that you also meet all of these conditions:", - "", - " a) The work must carry prominent notices stating that you modified", - " it, and giving a relevant date.", - "", - " b) The work must carry prominent notices stating that it is", - " released under this License and any conditions added under section", - " 7. This requirement modifies the requirement in section 4 to", - " 'keep intact all notices'.", - "", - " c) You must license the entire work, as a whole, under this", - " License to anyone who comes into possession of a copy. This", - " License will therefore apply, along with any applicable section 7", - " additional terms, to the whole of the work, and all its parts,", - " regardless of how they are packaged. This License gives no", - " permission to license the work in any other way, but it does not", - " invalidate such permission if you have separately received it.", - "", - " d) If the work has interactive user interfaces, each must display", - " Appropriate Legal Notices; however, if the Program has interactive", - " interfaces that do not display Appropriate Legal Notices, your", - " work need not make them do so.", - "", - " A compilation of a covered work with other separate and independent", - "works, which are not by their nature extensions of the covered work,", - "and which are not combined with it such as to form a larger program,", - "in or on a volume of a storage or distribution medium, is called an", - "'aggregate' if the compilation and its resulting copyright are not", - "used to limit the access or legal rights of the compilation's users", - "beyond what the individual works permit. Inclusion of a covered work", - "in an aggregate does not cause this License to apply to the other", - "parts of the aggregate.", - "", - " 6. Conveying Non-Source Forms.", - "", - " You may convey a covered work in object code form under the terms", - "of sections 4 and 5, provided that you also convey the", - "machine-readable Corresponding Source under the terms of this License,", - "in one of these ways:", - "", - " a) Convey the object code in, or embodied in, a physical product", - " (including a physical distribution medium), accompanied by the", - " Corresponding Source fixed on a durable physical medium", - " customarily used for software interchange.", - "", - " b) Convey the object code in, or embodied in, a physical product", - " (including a physical distribution medium), accompanied by a", - " written offer, valid for at least three years and valid for as", - " long as you offer spare parts or customer support for that product", - " model, to give anyone who possesses the object code either (1) a", - " copy of the Corresponding Source for all the software in the", - " product that is covered by this License, on a durable physical", - " medium customarily used for software interchange, for a price no", - " more than your reasonable cost of physically performing this", - " conveying of source, or (2) access to copy the", - " Corresponding Source from a network server at no charge.", - "", - " c) Convey individual copies of the object code with a copy of the", - " written offer to provide the Corresponding Source. This", - " alternative is allowed only occasionally and noncommercially, and", - " only if you received the object code with such an offer, in accord", - " with subsection 6b.", - "", - " d) Convey the object code by offering access from a designated", - " place (gratis or for a charge), and offer equivalent access to the", - " Corresponding Source in the same way through the same place at no", - " further charge. You need not require recipients to copy the", - " Corresponding Source along with the object code. If the place to", - " copy the object code is a network server, the Corresponding Source", - " may be on a different server (operated by you or a third party)", - " that supports equivalent copying facilities, provided you maintain", - " clear directions next to the object code saying where to find the", - " Corresponding Source. Regardless of what server hosts the", - " Corresponding Source, you remain obligated to ensure that it is", - " available for as long as needed to satisfy these requirements.", - "", - " e) Convey the object code using peer-to-peer transmission, provided", - " you inform other peers where the object code and Corresponding", - " Source of the work are being offered to the general public at no", - " charge under subsection 6d.", - "", - " A separable portion of the object code, whose source code is excluded", - "from the Corresponding Source as a System Library, need not be", - "included in conveying the object code work.", - "", - " A 'User Product' is either (1) a 'consumer product', which means any", - "tangible personal property which is normally used for personal, family,", - "or household purposes, or (2) anything designed or sold for incorporation", - "into a dwelling. In determining whether a product is a consumer product,", - "doubtful cases shall be resolved in favor of coverage. For a particular", - "product received by a particular user, 'normally used' refers to a", - "typical or common use of that class of product, regardless of the status", - "of the particular user or of the way in which the particular user", - "actually uses, or expects or is expected to use, the product. A product", - "is a consumer product regardless of whether the product has substantial", - "commercial, industrial or non-consumer uses, unless such uses represent", - "the only significant mode of use of the product.", - "", - " 'Installation Information' for a User Product means any methods,", - "procedures, authorization keys, or other information required to install", - "and execute modified versions of a covered work in that User Product from", - "a modified version of its Corresponding Source. The information must", - "suffice to ensure that the continued functioning of the modified object", - "code is in no case prevented or interfered with solely because", - "modification has been made.", - "", - " If you convey an object code work under this section in, or with, or", - "specifically for use in, a User Product, and the conveying occurs as", - "part of a transaction in which the right of possession and use of the", - "User Product is transferred to the recipient in perpetuity or for a", - "fixed term (regardless of how the transaction is characterized), the", - "Corresponding Source conveyed under this section must be accompanied", - "by the Installation Information. But this requirement does not apply", - "if neither you nor any third party retains the ability to install", - "modified object code on the User Product (for example, the work has", - "been installed in ROM).", - "", - " The requirement to provide Installation Information does not include a", - "requirement to continue to provide support service, warranty, or updates", - "for a work that has been modified or installed by the recipient, or for", - "the User Product in which it has been modified or installed. Access to a", - "network may be denied when the modification itself materially and", - "adversely affects the operation of the network or violates the rules and", - "protocols for communication across the network.", - "", - " Corresponding Source conveyed, and Installation Information provided,", - "in accord with this section must be in a format that is publicly", - "documented (and with an implementation available to the public in", - "source code form), and must require no special password or key for", - "unpacking, reading or copying.", - "", - " 7. Additional Terms.", - "", - " 'Additional permissions' are terms that supplement the terms of this", - "License by making exceptions from one or more of its conditions.", - "Additional permissions that are applicable to the entire Program shall", - "be treated as though they were included in this License, to the extent", - "that they are valid under applicable law. If additional permissions", - "apply only to part of the Program, that part may be used separately", - "under those permissions, but the entire Program remains governed by", - "this License without regard to the additional permissions.", - "", - " When you convey a copy of a covered work, you may at your option", - "remove any additional permissions from that copy, or from any part of", - "it. (Additional permissions may be written to require their own", - "removal in certain cases when you modify the work.) You may place", - "additional permissions on material, added by you to a covered work,", - "for which you have or can give appropriate copyright permission.", - "", - " Notwithstanding any other provision of this License, for material you", - "add to a covered work, you may (if authorized by the copyright holders of", - "that material) supplement the terms of this License with terms:", - "", - " a) Disclaiming warranty or limiting liability differently from the", - " terms of sections 15 and 16 of this License; or", - "", - " b) Requiring preservation of specified reasonable legal notices or", - " author attributions in that material or in the Appropriate Legal", - " Notices displayed by works containing it; or", - "", - " c) Prohibiting misrepresentation of the origin of that material, or", - " requiring that modified versions of such material be marked in", - " reasonable ways as different from the original version; or", - "", - " d) Limiting the use for publicity purposes of names of licensors or", - " authors of the material; or", - "", - " e) Declining to grant rights under trademark law for use of some", - " trade names, trademarks, or service marks; or", - "", - " f) Requiring indemnification of licensors and authors of that", - " material by anyone who conveys the material (or modified versions of", - " it) with contractual assumptions of liability to the recipient, for", - " any liability that these contractual assumptions directly impose on", - " those licensors and authors.", - "", - " All other non-permissive additional terms are considered 'further", - "restrictions' within the meaning of section 10. If the Program as you", - "received it, or any part of it, contains a notice stating that it is", - "governed by this License along with a term that is a further", - "restriction, you may remove that term. If a license document contains", - "a further restriction but permits relicensing or conveying under this", - "License, you may add to a covered work material governed by the terms", - "of that license document, provided that the further restriction does", - "not survive such relicensing or conveying.", - "", - " If you add terms to a covered work in accord with this section, you", - "must place, in the relevant source files, a statement of the", - "additional terms that apply to those files, or a notice indicating", - "where to find the applicable terms.", - "", - " Additional terms, permissive or non-permissive, may be stated in the", - "form of a separately written license, or stated as exceptions;", - "the above requirements apply either way.", - "", - " 8. Termination.", - "", - " You may not propagate or modify a covered work except as expressly", - "provided under this License. Any attempt otherwise to propagate or", - "modify it is void, and will automatically terminate your rights under", - "this License (including any patent licenses granted under the third", - "paragraph of section 11).", - "", - " However, if you cease all violation of this License, then your", - "license from a particular copyright holder is reinstated (a)", - "provisionally, unless and until the copyright holder explicitly and", - "finally terminates your license, and (b) permanently, if the copyright", - "holder fails to notify you of the violation by some reasonable means", - "prior to 60 days after the cessation.", - "", - " Moreover, your license from a particular copyright holder is", - "reinstated permanently if the copyright holder notifies you of the", - "violation by some reasonable means, this is the first time you have", - "received notice of violation of this License (for any work) from that", - "copyright holder, and you cure the violation prior to 30 days after", - "your receipt of the notice.", - "", - " Termination of your rights under this section does not terminate the", - "licenses of parties who have received copies or rights from you under", - "this License. If your rights have been terminated and not permanently", - "reinstated, you do not qualify to receive new licenses for the same", - "material under section 10.", - "", - " 9. Acceptance Not Required for Having Copies.", - "", - " You are not required to accept this License in order to receive or", - "run a copy of the Program. Ancillary propagation of a covered work", - "occurring solely as a consequence of using peer-to-peer transmission", - "to receive a copy likewise does not require acceptance. However,", - "nothing other than this License grants you permission to propagate or", - "modify any covered work. These actions infringe copyright if you do", - "not accept this License. Therefore, by modifying or propagating a", - "covered work, you indicate your acceptance of this License to do so.", - "", - " 10. Automatic Licensing of Downstream Recipients.", - "", - " Each time you convey a covered work, the recipient automatically", - "receives a license from the original licensors, to run, modify and", - "propagate that work, subject to this License. You are not responsible", - "for enforcing compliance by third parties with this License.", - "", - " An 'entity transaction' is a transaction transferring control of an", - "organization, or substantially all assets of one, or subdividing an", - "organization, or merging organizations. If propagation of a covered", - "work results from an entity transaction, each party to that", - "transaction who receives a copy of the work also receives whatever", - "licenses to the work the party's predecessor in interest had or could", - "give under the previous paragraph, plus a right to possession of the", - "Corresponding Source of the work from the predecessor in interest, if", - "the predecessor has it or can get it with reasonable efforts.", - "", - " You may not impose any further restrictions on the exercise of the", - "rights granted or affirmed under this License. For example, you may", - "not impose a license fee, royalty, or other charge for exercise of", - "rights granted under this License, and you may not initiate litigation", - "(including a cross-claim or counterclaim in a lawsuit) alleging that", - "any patent claim is infringed by making, using, selling, offering for", - "sale, or importing the Program or any portion of it.", - "", - " 11. Patents.", - "", - " A 'contributor' is a copyright holder who authorizes use under this", - "License of the Program or a work on which the Program is based. The", - "work thus licensed is called the contributor's 'contributor version'.", - "", - " A contributor's 'essential patent claims' are all patent claims", - "owned or controlled by the contributor, whether already acquired or", - "hereafter acquired, that would be infringed by some manner, permitted", - "by this License, of making, using, or selling its contributor version,", - "but do not include claims that would be infringed only as a", - "consequence of further modification of the contributor version. For", - "purposes of this definition, 'control' includes the right to grant", - "patent sublicenses in a manner consistent with the requirements of", - "this License.", - "", - " Each contributor grants you a non-exclusive, worldwide, royalty-free", - "patent license under the contributor's essential patent claims, to", - "make, use, sell, offer for sale, import and otherwise run, modify and", - "propagate the contents of its contributor version.", - "", - " In the following three paragraphs, a 'patent license' is any express", - "agreement or commitment, however denominated, not to enforce a patent", - "(such as an express permission to practice a patent or covenant not to", - "sue for patent infringement). To 'grant' such a patent license to a", - "party means to make such an agreement or commitment not to enforce a", - "patent against the party.", - "", - " If you convey a covered work, knowingly relying on a patent license,", - "and the Corresponding Source of the work is not available for anyone", - "to copy, free of charge and under the terms of this License, through a", - "publicly available network server or other readily accessible means,", - "then you must either (1) cause the Corresponding Source to be so", - "available, or (2) arrange to deprive yourself of the benefit of the", - "patent license for this particular work, or (3) arrange, in a manner", - "consistent with the requirements of this License, to extend the patent", - "license to downstream recipients. 'Knowingly relying' means you have", - "actual knowledge that, but for the patent license, your conveying the", - "covered work in a country, or your recipient's use of the covered work", - "in a country, would infringe one or more identifiable patents in that", - "country that you have reason to believe are valid.", - "", - " If, pursuant to or in connection with a single transaction or", - "arrangement, you convey, or propagate by procuring conveyance of, a", - "covered work, and grant a patent license to some of the parties", - "receiving the covered work authorizing them to use, propagate, modify", - "or convey a specific copy of the covered work, then the patent license", - "you grant is automatically extended to all recipients of the covered", - "work and works based on it.", - "", - " A patent license is 'discriminatory' if it does not include within", - "the scope of its coverage, prohibits the exercise of, or is", - "conditioned on the non-exercise of one or more of the rights that are", - "specifically granted under this License. You may not convey a covered", - "work if you are a party to an arrangement with a third party that is", - "in the business of distributing software, under which you make payment", - "to the third party based on the extent of your activity of conveying", - "the work, and under which the third party grants, to any of the", - "parties who would receive the covered work from you, a discriminatory", - "patent license (a) in connection with copies of the covered work", - "conveyed by you (or copies made from those copies), or (b) primarily", - "for and in connection with specific products or compilations that", - "contain the covered work, unless you entered into that arrangement,", - "or that patent license was granted, prior to 28 March 2007.", - "", - " Nothing in this License shall be construed as excluding or limiting", - "any implied license or other defenses to infringement that may", - "otherwise be available to you under applicable patent law.", - "", - " 12. No Surrender of Others' Freedom.", - "", - " If conditions are imposed on you (whether by court order, agreement or", - "otherwise) that contradict the conditions of this License, they do not", - "excuse you from the conditions of this License. If you cannot convey a", - "covered work so as to satisfy simultaneously your obligations under this", - "License and any other pertinent obligations, then as a consequence you may", - "not convey it at all. For example, if you agree to terms that obligate you", - "to collect a royalty for further conveying from those to whom you convey", - "the Program, the only way you could satisfy both those terms and this", - "License would be to refrain entirely from conveying the Program.", - "", - " 13. Use with the GNU Affero General Public License.", - "", - " Notwithstanding any other provision of this License, you have", - "permission to link or combine any covered work with a work licensed", - "under version 3 of the GNU Affero General Public License into a single", - "combined work, and to convey the resulting work. The terms of this", - "License will continue to apply to the part which is the covered work,", - "but the special requirements of the GNU Affero General Public License,", - "section 13, concerning interaction through a network will apply to the", - "combination as such.", - "", - " 14. Revised Versions of this License.", - "", - " The Free Software Foundation may publish revised and/or new versions of", - "the GNU General Public License from time to time. Such new versions will", - "be similar in spirit to the present version, but may differ in detail to", - "address new problems or concerns.", - "", - " Each version is given a distinguishing version number. If the", - "Program specifies that a certain numbered version of the GNU General", - "Public License 'or any later version' applies to it, you have the", - "option of following the terms and conditions either of that numbered", - "version or of any later version published by the Free Software", - "Foundation. If the Program does not specify a version number of the", - "GNU General Public License, you may choose any version ever published", - "by the Free Software Foundation.", - "", - " If the Program specifies that a proxy can decide which future", - "versions of the GNU General Public License can be used, that proxy's", - "public statement of acceptance of a version permanently authorizes you", - "to choose that version for the Program.", - "", - " Later license versions may give you additional or different", - "permissions. However, no additional obligations are imposed on any", - "author or copyright holder as a result of your choosing to follow a", - "later version.", - "", - " 15. Disclaimer of Warranty.", - "", - " THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY", - "APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT", - "HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM 'AS IS' WITHOUT WARRANTY", - "OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,", - "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", - "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM", - "IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF", - "ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", - "", - " 16. Limitation of Liability.", - "", - " IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING", - "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS", - "THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY", - "GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE", - "USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF", - "DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD", - "PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),", - "EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF", - "SUCH DAMAGES.", - "", - " 17. Interpretation of Sections 15 and 16.", - "", - " If the disclaimer of warranty and limitation of liability provided", - "above cannot be given local legal effect according to their terms,", - "reviewing courts shall apply local law that most closely approximates", - "an absolute waiver of all civil liability in connection with the", - "Program, unless a warranty or assumption of liability accompanies a", - "copy of the Program in return for a fee.", - "", - " END OF TERMS AND CONDITIONS", - "", - " How to Apply These Terms to Your New Programs", - "", - " If you develop a new program, and you want it to be of the greatest", - "possible use to the public, the best way to achieve this is to make it", - "free software which everyone can redistribute and change under these terms.", - "", - " To do so, attach the following notices to the program. It is safest", - "to attach them to the start of each source file to most effectively", - "state the exclusion of warranty; and each file should have at least", - "the 'copyright' line and a pointer to where the full notice is found.", - "", - " ", - " Copyright (C) ", - "", - " This program is free software: you can redistribute it and/or modify", - " it under the terms of the GNU General Public License as published by", - " the Free Software Foundation, either version 3 of the License, or", - " (at your option) any later version.", - "", - " This program is distributed in the hope that it will be useful,", - " but WITHOUT ANY WARRANTY; without even the implied warranty of", - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", - " GNU General Public License for more details.", - "", - " You should have received a copy of the GNU General Public License", - " along with this program. If not, see .", - "", - "Also add information on how to contact you by electronic and paper mail.", - "", - " If the program does terminal interaction, make it output a short", - "notice like this when it starts in an interactive mode:", - "", - " Copyright (C) ", - " This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.", - " This is free software, and you are welcome to redistribute it", - " under certain conditions; type `show c' for details.", - "", - "The hypothetical commands `show w' and `show c' should show the appropriate", - "parts of the General Public License. Of course, your program's commands", - "might be different; for a GUI interface, you would use an 'about box'.", - "", - " You should also get your employer (if you work as a programmer) or school,", - "if any, to sign a 'copyright disclaimer' for the program, if necessary.", - "For more information on this, and how to apply and follow the GNU GPL, see", - ".", - "", - " The GNU General Public License does not permit incorporating your program", - "into proprietary programs. If your program is a subroutine library, you", - "may consider it more useful to permit linking proprietary applications with", - "the library. If this is what you want to do, use the GNU Lesser General", - "Public License instead of this License. But first, please read", - ".", - "--- End of License ---" -}; -const int license_num_lines = sizeof(license_pages) / sizeof(char*); - -static void show_license() { - int top_line = 0; - int needs_redraw = 1; - - while (1) { - if (needs_redraw) { - print_clear(); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - for (int i = 0; i < 24 && (top_line + i) < license_num_lines; i++) { - brew_str(license_pages[top_line + i]); - brew_str("\n"); - } - print_set_color(PRINT_INDEX_15, PRINT_INDEX_9); - brew_str("-- (Up/Down to scroll, 'q' to quit) --"); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - needs_redraw = 0; - } - - // Wait for a key press before doing anything - while (!check_keyboard()) { /* Do nothing */ } - - unsigned char sc = read_scan_code(); // Now read the key - if (sc == 0x48 && top_line > 0) { top_line--; needs_redraw = 1; } // Up Arrow - else if (sc == 0x50 && (top_line + 24) < license_num_lines) { top_line++; needs_redraw = 1; } // Down Arrow - else if (scan_code_to_ascii(sc) == 'q') { - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - break; - } - brewing(10000000); // Delay to handle keyboard typematic rate (key-repeat) - } -} - - -#endif // APPS_MAN_H diff --git a/src/kernel/cli_apps_old/man.h b/src/kernel/cli_apps_old/man.h deleted file mode 100644 index 7ff0ca5..0000000 --- a/src/kernel/cli_apps_old/man.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_MAN_H -#define APPS_MAN_H - -#include "print.h" -#include "keyboard.h" - -const char* manual_pages[] = { - "BrewKernel User Manual", - "----------------------", - "", - "Welcome to the BrewKernel, a simple hobby operating system kernel designed", - "for x86_64 architecture. This manual provides an overview of the system,", - "its features, and available commands.", - "", - "== System Overview ==", - "BrewKernel boots into a VGA text mode display (80x25 characters). It", - "initializes a custom color palette and provides basic keyboard input", - "handling. The primary user interface is a simple command-line", - "interface (CLI).", - "", - "== Features ==", - "* Ramdisk-based Filesystem: A simple in-memory filesystem supporting", - " files and directories.", - "* VGA Text Mode Driver: Full control over text and background colors.", - "* PS/2 Keyboard Driver: Handles key presses, including modifier keys", - " like Shift.", - "* Simple CLI: A basic shell to interact with the kernel.", - "* Command History (sort of): The last entered command remains in the", - " buffer but is not yet a full history feature.", - "", - "== How to Use the CLI ==", - "Upon boot, you can type 'CLI' and press Enter to start the command-line", - "interface. Once in the CLI, you can type commands followed by Enter.", - "Commands are case-insensitive.", - "", - "== Special Keys ==", - "* Up/down arrow keys, scrolls through command history. (CLI mode only)", - "", - "== File System ==", - "The BrewKernel includes a simple ramdisk-based filesystem. You can create,", - "read, write, and list files and directories using the following commands:", - "This filesystem will NOT save to disk and only saves to RAM.", - "This filesystem is UNIX like, using '/' as the directory separator.", - "Commands like ls, cd, mkdir work with absolute and relative paths.", - "", - "== Brew Language==", - "== This version of brewkernel contains a simple interpreter for the", - "== brew programming language. Currently the only implemented function is", - "== brew_str, which prints a string to the screen. More features will be", - "== added in future versions. Brew files have the extension .brew", - "== you can run a brew file using the command: brewer >filename.brew<", - "== Available Commands ==", - "HELP: Displays a short list of available commands.", - "LS [path]: Lists files in the specified directory or current directory if", - " no path is given.", - "", - "CD [path]: Changes the current directory to 'path'.", - "", - "PWD: Prints the current working directory path.", - "", - "MKDIR [path]: Creates a new directory at the specified path.", - "", - "MAN: Shows this detailed user manual. Use UP/DOWN arrow keys to", - " scroll and 'q' to quit the manual viewer.", - "", - "ABOUT: Displays information about the kernel, including version, build", - " date, architecture, and compiler.", - "", - "MATH:", - "A simple calculator for basic arithmetic operations", - "(add, subtract, multiply, divide) on integers.", - - "", - "DATE: Displays the current date and time, with an option to select your", - " timezone.", - "", - "TXTEDIT: A simple text editor. Features:", - " - Create and edit multiple text files", - " - Files are preserved between editor sessions (until reboot)", - " - Navigate with arrow keys", - " - Save/load files with custom names", - " - ESC to exit (with save prompt)", - "USAGE: txtedit >filename< or:", - "txtedit and choose name on save", - "", - "IREADTHEMANUAL: Wow. You actually read the manual. Run this command", - " for a special surprise!", - "", - "CLEAR: Clears the entire screen and moves the cursor to the top-left.", - "", - "EXIT: Exits the CLI mode and returns to the initial kernel screen.", - "", - "LICENSE: Displays the full GNU General Public License v3, under which", - " BrewKernel is distributed. Use UP/DOWN to scroll, 'q' to quit.", - "", - "COWSAY: Moo! Displays a cow saying a message. Usage: COWSAY [message]", - " Inspired by GNU/LINUX", - "", - "UPTIME: Shows how long the system has been running since boot.", - "BEEP: Makes a beep sound using the PC speaker.", - "--- End of Manual ---" -}; -const int manual_num_lines = sizeof(manual_pages) / sizeof(char*); - -static void show_manual() { - int top_line = 0; - int needs_redraw = 1; - - while (1) { - if (needs_redraw) { - print_clear(); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - for (int i = 0; i < 24 && (top_line + i) < manual_num_lines; i++) { - brew_str(manual_pages[top_line + i]); - brew_str("\n"); - } - print_set_color(PRINT_INDEX_15, PRINT_INDEX_9); - brew_str("-- (Up/Down to scroll, 'q' to quit) --"); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - needs_redraw = 0; - } - - // Wait for a key press before doing anything - while (!check_keyboard()) { /* Do nothing */ } - - unsigned char sc = read_scan_code(); // Now read the key - if (sc == 0x48 && top_line > 0) { top_line--; needs_redraw = 1; } // Up Arrow - else if (sc == 0x50 && (top_line + 24) < manual_num_lines) { top_line++; needs_redraw = 1; } // Down Arrow - else if (scan_code_to_ascii(sc) == 'q') { - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); - break; - } - - brewing(10000000); // Delay to handle keyboard typematic rate (key-repeat) - } -} - - -#endif // APPS_MAN_H diff --git a/src/kernel/cli_apps_old/math.h b/src/kernel/cli_apps_old/math.h deleted file mode 100644 index 6b40a29..0000000 --- a/src/kernel/cli_apps_old/math.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_MATH_H -#define APPS_MATH_H - -#include "print.h" -#include "keyboard.h" - -extern int buffer_pos; - -static void math_cmd() { - brew_str("\nMath Calculator\n"); - brew_str("Choose operation:\n"); - brew_str("1. Addition (+)\n"); - brew_str("2. Subtraction (-)\n"); - brew_str("3. Multiplication (*)\n"); - brew_str("4. Division (/)\n"); - brew_str("\nEnter operation number: "); - - // Clear buffer for new input - buffer_pos = 0; - - // Wait for operation choice - while (1) { - if (check_keyboard()) { - unsigned char scan_code = read_scan_code(); - char ascii_char = scan_code_to_ascii(scan_code); - - if (ascii_char >= '1' && ascii_char <= '4') { - print_char(ascii_char); - char operation = ascii_char; - brew_str("\nEnter first number: "); - - // Get first number - buffer_pos = 0; - int first_num = 0; - while (1) { - if (check_keyboard()) { - scan_code = read_scan_code(); - ascii_char = scan_code_to_ascii(scan_code); - - if (ascii_char >= '0' && ascii_char <= '9') { - print_char(ascii_char); - first_num = first_num * 10 + (ascii_char - '0'); - } else if (ascii_char == '\n' || ascii_char == '\r') { - break; - } - } - } - - brew_str("\nEnter second number: "); - - // Get second number - buffer_pos = 0; - int second_num = 0; - while (1) { - if (check_keyboard()) { - scan_code = read_scan_code(); - ascii_char = scan_code_to_ascii(scan_code); - - if (ascii_char >= '0' && ascii_char <= '9') { - print_char(ascii_char); - second_num = second_num * 10 + (ascii_char - '0'); - } else if (ascii_char == '\n' || ascii_char == '\r') { - break; - } - } - } - - brew_str("\nResult: "); - switch (operation) { - case '1': - brew_str("\n"); - brew_int(first_num); - brew_str(" + "); - brew_int(second_num); - brew_str(" = "); - brew_int(first_num + second_num); - break; - case '2': - brew_str("\n"); - brew_int(first_num); - brew_str(" - "); - brew_int(second_num); - brew_str(" = "); - brew_int(first_num - second_num); - break; - case '3': - brew_str("\n"); - brew_int(first_num); - brew_str(" * "); - brew_int(second_num); - brew_str(" = "); - brew_int(first_num * second_num); - break; - case '4': - if (second_num == 0) { - brew_str("Error: Division by zero!\n"); - } else { - brew_str("\n"); - brew_int(first_num); - brew_str(" / "); - brew_int(second_num); - brew_str(" = "); - brew_int(first_num / second_num); - } - break; - } - brew_str("\n"); - break; - } - } - } - } - -#endif // APPS_MATH_H \ No newline at end of file diff --git a/src/kernel/cli_apps_old/readtheman.h b/src/kernel/cli_apps_old/readtheman.h deleted file mode 100644 index 44a72a2..0000000 --- a/src/kernel/cli_apps_old/readtheman.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef APPS_NERD_H -#define APPS_NERD_H - -#include "../io.h" -#include "../print.h" - -static void nerd() { - brew_str("\n"); - brew_str("You read the manual? NERD. you know what?\n"); - brew_str("Fuck you.\n"); - brewing(5000000000); - - - // Set the PIT to the desired frequency (1000 Hz for high pitch) - outb(0x43, 0xB6); // Command byte: channel 2, mode 3, binary - int frequency = 1000; - int divisor = 1193180 / frequency; - outb(0x42, divisor & 0xFF); - outb(0x42, (divisor >> 8) & 0xFF); - - outb(0x61, inb(0x61) | 0x03); - - for(int i = 0; i < 1000000000000000000; i++) { - print_set_color(PRINT_INDEX_0, PRINT_INDEX_15); // black on white - print_clear(); - brewing(500000); - - print_set_color(PRINT_INDEX_15, PRINT_INDEX_0); // white on black - print_clear(); - brewing(500000); - } - -} - -#endif // APPS_NERD_H diff --git a/src/kernel/cli_apps_old/reboot.h b/src/kernel/cli_apps_old/reboot.h deleted file mode 100644 index 4fd0bb1..0000000 --- a/src/kernel/cli_apps_old/reboot.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef REBOOT_H -#define REBOOT_H - -#include "../print.h" -#include "../io.h" - -void brewing(int iterations); - -void reboot_command() { - brew_str("\nInitiating system reboot...\n"); - brewing(10000000); - while ((inb(0x64) & 2) != 0) { - brewing(1000); - } - outb(0x64, 0xFE); - brewing(50000000); - asm volatile ("lidt %0" : : "m"(*(char*)0)); - asm volatile ("int $0x3"); - brew_str("WARNING: System reboot failed.\n"); - brew_str("Please reset your computer manually.\n"); -} - -#endif \ No newline at end of file diff --git a/src/kernel/cli_apps_old/shutdown.h b/src/kernel/cli_apps_old/shutdown.h deleted file mode 100644 index b04bf94..0000000 --- a/src/kernel/cli_apps_old/shutdown.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef SHUTDOWN_H -#define SHUTDOWN_H - -#include "../print.h" -#include "../io.h" - -void brewing(int iterations); - -void shutdown_command() { - brew_str("\nInitiating system shutdown...\n"); - brewing(10000000); - outw(0xB004, 0x2000); - outb(0x64, 0xFE); - brew_str("WARNING: System shutdown failed.\n"); - brew_str("It is now safe to turn off your computer.\n"); -} - -#endif \ No newline at end of file diff --git a/src/kernel/cli_apps_old/txtedit.h b/src/kernel/cli_apps_old/txtedit.h deleted file mode 100644 index 0adce92..0000000 --- a/src/kernel/cli_apps_old/txtedit.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef TXTEDIT_H -#define TXTEDIT_H - -#include "../print.h" -#include "../keyboard.h" -#include "../filesys.h" -#include "../file.h" - -#define BUFFER_SIZE 4096 -#define MAX_LINES 25 -#define MAX_LINE_LENGTH 80 - -// Helper string functions for txtedit -static int strcmp_txtedit(const char *s1, const char *s2) { - while (*s1 && (*s1 == *s2)) { - s1++; - s2++; - } - return *(const unsigned char*)s1 - *(const unsigned char*)s2; -} - -static size_t strlen_txtedit(const char* str) { - size_t len = 0; - while (str[len]) len++; - return len; -} - -// Buffer for the current file being edited -static char text_buffer[BUFFER_SIZE]; -static int buffer_size = 0; -static int cursor_pos = 0; -static int cursor_row = 0; -static int cursor_col = 0; -static int scroll_offset = 0; // Line number at top of visible area -static int has_unsaved_changes = 0; // Flag to track if file has been modified -#define ESC_KEY 0x01 -#define ENTER_KEY 0x1C -#define BACKSPACE_KEY 0x0E -#define SCAN_CODE_LEFT_ARROW 0x4B -#define SCAN_CODE_RIGHT_ARROW 0x4D -#define VISIBLE_LINES 23 // Lines 0-22 visible (line 23 is status) - -// Status messages -static const char* MSG_SAVED = "Text saved to RAM buffer"; -static const char* MSG_LOADED = "Text loaded from RAM buffer"; -static const char* MSG_HELP = "ESC:Exit ENTER:NewLine Arrows:Navigate"; - -static void draw_status_line(const char* msg) { - size_t row, col; - print_get_cursor_pos(&row, &col); - print_set_cursor_pos(24, 0); // Bottom line - print_set_color(PRINT_INDEX_0, PRINT_INDEX_7); // Black on light grey - for(int i = 0; i < 80; i++) print_char(' '); // Clear line - print_set_cursor_pos(24, 0); - brew_str(msg); - print_set_cursor_pos(row, col); - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); // Reset colors to latte -} - -static void get_filename(char* filename) { - int pos = 0; - print_clear(); - brew_str("Enter filename (e.g., file.txt): "); - - while(1) { - if(check_keyboard()) { - unsigned char scan_code = read_scan_code(); - - if(scan_code == 0x1C) { // Enter - filename[pos] = '\0'; - break; - } - else if(scan_code == 0x0E) { // Backspace - if(pos > 0) { - pos--; - print_backspace(); - } - } - else { - char c = scan_code_to_ascii(scan_code); - if(c && pos < FS_MAX_FILENAME - 1) { - filename[pos++] = c; - print_char(c); - } - } - } - } -} - -static char current_filename[FS_MAX_FILENAME]; - -static void save_current_buffer(const char* text_buffer, int buffer_size, bool prompt_for_filename) { - // If we don't have a current filename and need to prompt, ask for one - if (current_filename[0] == '\0' && prompt_for_filename) { - get_filename(current_filename); - } else if (current_filename[0] == '\0') { - draw_status_line("Error: No filename specified"); - return; - } - - // Create a new file in the current directory - File* file = fs_find_file(current_filename); - if (!file) { - file = fs_create_file(current_filename); - } - - if (file && file_write_content(file, text_buffer, buffer_size)) { - draw_status_line("File saved successfully"); - } else { - draw_status_line("Error: Could not save file"); - } -} - -static void calculate_cursor_position() { - // Calculate cursor position based on buffer position - cursor_row = 0; - cursor_col = 0; - int current_line = 0; - - for(int i = 0; i < cursor_pos && i < buffer_size; i++) { - if(text_buffer[i] == '\n') { - current_line++; - cursor_col = 0; - } else { - cursor_col++; - } - } - - // Adjust display row based on scroll offset - cursor_row = current_line - scroll_offset; - - // Auto-scroll up if cursor goes above visible area - if(cursor_row < 0) { - scroll_offset += cursor_row; - cursor_row = 0; - } - - // Auto-scroll down if cursor goes below visible area - if(cursor_row >= VISIBLE_LINES) { - scroll_offset += (cursor_row - VISIBLE_LINES + 1); - cursor_row = VISIBLE_LINES - 1; - } -} - -static void redraw_screen() { - print_disable_cursor(); - - print_clear(); - print_set_cursor_pos(0, 0); - - // Draw the text buffer, starting from scroll_offset - int current_line = 0; - int display_line = 0; - - for(int i = 0; i < buffer_size && display_line < VISIBLE_LINES; i++) { - // Skip lines until we reach scroll_offset - if(current_line < scroll_offset) { - if(text_buffer[i] == '\n') { - current_line++; - } - continue; - } - - // We're now in the visible area - if(text_buffer[i] == '\n') { - print_char('\n'); - current_line++; - display_line++; - if(display_line >= VISIBLE_LINES) break; - } else { - print_char(text_buffer[i]); - } - } - - // Calculate cursor position based on cursor_pos in buffer - calculate_cursor_position(); - - draw_status_line(MSG_HELP); - // Position cursor correctly and re-enable it - print_set_cursor_pos(cursor_row, cursor_col); - print_enable_cursor(); -} - -static void insert_char(char c) { - if(buffer_size >= BUFFER_SIZE - 1) return; - - // Move following text forward - for(int i = buffer_size; i > cursor_pos; i--) { - text_buffer[i] = text_buffer[i-1]; - } - - text_buffer[cursor_pos] = c; - cursor_pos++; - buffer_size++; - has_unsaved_changes = 1; // Mark file as modified - - // Redraw the screen to properly display the inserted character - redraw_screen(); -} - -static void delete_char() { - if(cursor_pos <= 0) return; - - cursor_pos--; - // Move following text backward - for(int i = cursor_pos; i < buffer_size - 1; i++) { - text_buffer[i] = text_buffer[i+1]; - } - buffer_size--; - has_unsaved_changes = 1; // Mark file as modified - - // Redraw the screen to properly display after deletion - redraw_screen(); -} - -static void handle_special_key(unsigned char scan_code) { - switch(scan_code) { - case SCAN_CODE_UP_ARROW: { - // Find the start of the current line - int line_start = cursor_pos; - while(line_start > 0 && text_buffer[line_start - 1] != '\n') { - line_start--; - } - - // If we're on the first line, can't go up - if(line_start == 0) break; - - // Find the start of the previous line - int prev_line_start = line_start - 1; - while(prev_line_start > 0 && text_buffer[prev_line_start - 1] != '\n') { - prev_line_start--; - } - - // Calculate target column position - int target_col = cursor_pos - line_start; - - // Find the end of the previous line - int prev_line_end = prev_line_start; - while(prev_line_end < line_start - 1 && text_buffer[prev_line_end] != '\n') { - prev_line_end++; - } - - // Move cursor to same column in previous line (or end of line if shorter) - int prev_line_length = prev_line_end - prev_line_start; - cursor_pos = prev_line_start + (target_col < prev_line_length ? target_col : prev_line_length); - calculate_cursor_position(); - redraw_screen(); - break; - } - - case SCAN_CODE_DOWN_ARROW: { - // Find the start of the current line - int line_start = cursor_pos; - while(line_start > 0 && text_buffer[line_start - 1] != '\n') { - line_start--; - } - - // Find the end of the current line - int line_end = cursor_pos; - while(line_end < buffer_size && text_buffer[line_end] != '\n') { - line_end++; - } - - // If we're on the last line, can't go down - if(line_end >= buffer_size) break; - - // Move to start of next line - int next_line_start = line_end + 1; - if(next_line_start >= buffer_size) break; - - // Find the end of the next line - int next_line_end = next_line_start; - while(next_line_end < buffer_size && text_buffer[next_line_end] != '\n') { - next_line_end++; - } - - // Calculate target column position - int target_col = cursor_pos - line_start; - - // Move cursor to same column in next line (or end of line if shorter) - int next_line_length = next_line_end - next_line_start; - cursor_pos = next_line_start + (target_col < next_line_length ? target_col : next_line_length); - calculate_cursor_position(); - redraw_screen(); - break; - } - - case SCAN_CODE_LEFT_ARROW: - if(cursor_pos > 0) { - cursor_pos--; - calculate_cursor_position(); - redraw_screen(); - } - break; - - case SCAN_CODE_RIGHT_ARROW: - if(cursor_pos < buffer_size) { - cursor_pos++; - calculate_cursor_position(); - redraw_screen(); - } - break; - } -} - -static void load_file(const char* filename) { - File* file = fs_find_file(filename); - if (!file) { - draw_status_line("Creating new file"); - return; - } - - size_t size; - const char* content = file_get_content(file, &size); - if (!content || size > BUFFER_SIZE) { - draw_status_line("Error: Could not load file or file too large"); - return; - } - - // Copy content to buffer - for (size_t i = 0; i < size; i++) { - text_buffer[i] = content[i]; - } - buffer_size = size; - cursor_pos = 0; // Start at beginning of file - has_unsaved_changes = 0; // File is not modified after loading - draw_status_line("File loaded successfully"); -} - -void txtedit_run(const char* filename) { - print_set_color(PRINT_INDEX_7, PRINT_INDEX_0); // Set initial color to latte - - // Clear the buffers and filename - for(int i = 0; i < BUFFER_SIZE; i++) { - text_buffer[i] = 0; - } - buffer_size = 0; - cursor_pos = 0; - scroll_offset = 0; - has_unsaved_changes = 0; - current_filename[0] = '\0'; - - // If filename is provided, store it - if (filename) { - int i; - for (i = 0; filename[i] && i < FS_MAX_FILENAME - 1; i++) { - current_filename[i] = filename[i]; - } - current_filename[i] = '\0'; - load_file(filename); - } - - print_clear(); - redraw_screen(); - print_enable_cursor(); - - while(1) { - if(check_keyboard()) { - unsigned char scan_code = read_scan_code(); - - if(scan_code == ESC_KEY) { - // Only ask to save if there are unsaved changes - if(has_unsaved_changes) { - draw_status_line("Save before exit? (Y/N)"); - while(1) { - if(check_keyboard()) { - unsigned char save_scan = read_scan_code(); - char save_char = scan_code_to_ascii(save_scan); - if(save_char == 'Y' || save_char == 'y') { - // Only prompt for filename if we don't have one (started with txtedit with no args) - save_current_buffer(text_buffer, buffer_size, current_filename[0] == '\0'); - break; - } - else if(save_char == 'N' || save_char == 'n') { - break; - } - } - } - } - break; - } - else if(scan_code == ENTER_KEY) { - insert_char('\n'); - } - else if(scan_code == BACKSPACE_KEY) { - delete_char(); - } - else if(scan_code == SCAN_CODE_UP_ARROW || scan_code == SCAN_CODE_DOWN_ARROW || - scan_code == SCAN_CODE_LEFT_ARROW || scan_code == SCAN_CODE_RIGHT_ARROW) { - handle_special_key(scan_code); - } - else { - char c = scan_code_to_ascii(scan_code); - if(c) insert_char(c); - } - } - } - - -} - -#endif // TXTEDIT_H \ No newline at end of file diff --git a/src/kernel/cli_apps_old/uptime.h b/src/kernel/cli_apps_old/uptime.h deleted file mode 100644 index 5900012..0000000 --- a/src/kernel/cli_apps_old/uptime.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Brew Kernel - * Copyright (C) 2024-2026 boreddevnl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UPTIME_H -#define UPTIME_H - -#include "print.h" -#include "rtc.h" - -// Global variable to store boot time -static int boot_time_hour = -1; -static int boot_time_min = -1; -static int boot_time_sec = -1; - -// Initialize boot time -void init_uptime(void) { - if (boot_time_hour == -1) { - int year, month, day; - get_datetime(&year, &month, &day, &boot_time_hour, &boot_time_min, &boot_time_sec); - } -} - -// Function to print a zero-padded integer -static void brew_int_padded_uptime(int n) { - if (n >= 0 && n < 10) { - print_char('0'); - } - brew_int(n); -} - -// Calculate time difference considering wraparound -static void calc_time_diff(int start_h, int start_m, int start_s, - int curr_h, int curr_m, int curr_s, - int *diff_h, int *diff_m, int *diff_s) { - int total_start_secs = start_h * 3600 + start_m * 60 + start_s; - int total_curr_secs = curr_h * 3600 + curr_m * 60 + curr_s; - - // Handle day wraparound - if (total_curr_secs < total_start_secs) { - total_curr_secs += 24 * 3600; // Add a full day of seconds - } - - int diff_secs = total_curr_secs - total_start_secs; - - *diff_h = diff_secs / 3600; - diff_secs %= 3600; - *diff_m = diff_secs / 60; - *diff_s = diff_secs % 60; -} - -// Display uptime command -static void display_uptime(void) { - init_uptime(); // Ensure boot time is initialized - - int curr_hour, curr_min, curr_sec; - int year, month, day; - get_datetime(&year, &month, &day, &curr_hour, &curr_min, &curr_sec); - - int up_hours, up_minutes, up_seconds; - calc_time_diff(boot_time_hour, boot_time_min, boot_time_sec, - curr_hour, curr_min, curr_sec, - &up_hours, &up_minutes, &up_seconds); - - brew_str("\nSystem uptime: "); - if (up_hours > 0) { - brew_int(up_hours); - brew_str(" hour"); - if (up_hours != 1) brew_str("s"); - brew_str(" "); - } - if (up_minutes > 0 || up_hours > 0) { - brew_int(up_minutes); - brew_str(" minute"); - if (up_minutes != 1) brew_str("s"); - brew_str(" "); - } - brew_int(up_seconds); - brew_str(" second"); - if (up_seconds != 1) brew_str("s"); - brew_str("\n"); -} - -#endif // UPTIME_H \ No newline at end of file