mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 13:36:13 +03:00
Get nyancat nyanning in Serenity.
I found a cute program that renders an animated nyancat in the terminal. This patch adds enough hackery to get it working correctly. :^)
This commit is contained in:
parent
3944c00f23
commit
dddd0e7b03
Notes:
sideshowbarker
2024-07-19 15:52:48 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/dddd0e7b031
@ -81,6 +81,9 @@ RetainPtr<StringImpl> StringImpl::create(const char* cstring, size_t length, Sho
|
||||
if (!*cstring)
|
||||
return the_empty_stringimpl();
|
||||
|
||||
if (!length)
|
||||
return the_empty_stringimpl();
|
||||
|
||||
char* buffer;
|
||||
auto new_stringimpl = create_uninitialized(length, buffer);
|
||||
if (!new_stringimpl)
|
||||
|
@ -1425,6 +1425,20 @@ int Process::sys$kill(pid_t pid, int signal)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$usleep(useconds_t usec)
|
||||
{
|
||||
if (!usec)
|
||||
return 0;
|
||||
|
||||
sleep(usec / 1000);
|
||||
if (m_wakeup_time > system.uptime) {
|
||||
ASSERT(m_was_interrupted_while_blocked);
|
||||
dword ticks_left_until_original_wakeup_time = m_wakeup_time - system.uptime;
|
||||
return ticks_left_until_original_wakeup_time / TICKS_PER_SECOND;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$sleep(unsigned seconds)
|
||||
{
|
||||
if (!seconds)
|
||||
|
@ -166,6 +166,7 @@ public:
|
||||
int sys$getcwd(char*, size_t);
|
||||
int sys$chdir(const char*);
|
||||
int sys$sleep(unsigned seconds);
|
||||
int sys$usleep(useconds_t usec);
|
||||
int sys$gettimeofday(timeval*);
|
||||
int sys$gethostname(char* name, size_t length);
|
||||
int sys$get_arguments(int* argc, char*** argv);
|
||||
|
@ -62,6 +62,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
||||
break;
|
||||
case Syscall::SC_sleep:
|
||||
return current->sys$sleep((unsigned)arg1);
|
||||
case Syscall::SC_usleep:
|
||||
return current->sys$usleep((unsigned)arg1);
|
||||
case Syscall::SC_gettimeofday:
|
||||
return current->sys$gettimeofday((timeval*)arg1);
|
||||
case Syscall::SC_get_dir_entries:
|
||||
|
@ -84,6 +84,7 @@
|
||||
__ENUMERATE_SYSCALL(gui_set_global_cursor_tracking_enabled) \
|
||||
__ENUMERATE_SYSCALL(rmdir) \
|
||||
__ENUMERATE_SYSCALL(chmod) \
|
||||
__ENUMERATE_SYSCALL(usleep) \
|
||||
|
||||
|
||||
#ifdef SERENITY
|
||||
|
@ -16,6 +16,7 @@ typedef dword uid_t;
|
||||
typedef dword gid_t;
|
||||
typedef signed_word pid_t;
|
||||
typedef dword time_t;
|
||||
typedef dword useconds_t;
|
||||
typedef dword suseconds_t;
|
||||
|
||||
struct timeval {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -60,6 +61,15 @@ char* strdup(const char* str)
|
||||
return new_str;
|
||||
}
|
||||
|
||||
char* strndup(const char* str, size_t maxlen)
|
||||
{
|
||||
size_t len = min(strlen(str), maxlen);
|
||||
char* new_str = (char*)malloc(len + 1);
|
||||
memcpy(new_str, str, len);
|
||||
new_str[len] = 0;
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int strcmp(const char* s1, const char* s2)
|
||||
{
|
||||
while (*s1 == *s2++)
|
||||
|
@ -15,6 +15,8 @@ void* memchr(const void*, int c, size_t);
|
||||
void bzero(void*, size_t);
|
||||
void bcopy(const void*, void*, size_t);
|
||||
void* memset(void*, int, size_t);
|
||||
char* strdup(const char*);
|
||||
char* strndup(const char*, size_t);
|
||||
char* strcpy(char* dest, const char* src);
|
||||
char* strncpy(char* dest, const char* src, size_t);
|
||||
char* strchr(const char*, int c);
|
||||
|
@ -29,6 +29,7 @@ typedef uint32_t nlink_t;
|
||||
typedef uint32_t blksize_t;
|
||||
typedef uint32_t blkcnt_t;
|
||||
typedef uint32_t time_t;
|
||||
typedef uint32_t useconds_t;
|
||||
typedef uint32_t suseconds_t;
|
||||
typedef uint32_t clock_t;
|
||||
typedef uint32_t socklen_t;
|
||||
|
@ -30,5 +30,7 @@ time_t time(time_t*);
|
||||
char* ctime(const time_t*);
|
||||
void tzset();
|
||||
|
||||
#define difftime(t1,t0) (double)(t1 - t0)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
@ -201,6 +201,11 @@ int sleep(unsigned seconds)
|
||||
return syscall(SC_sleep, seconds);
|
||||
}
|
||||
|
||||
int usleep(useconds_t usec)
|
||||
{
|
||||
return syscall(SC_usleep, usec);
|
||||
}
|
||||
|
||||
int gethostname(char* buffer, size_t size)
|
||||
{
|
||||
int rc = syscall(SC_gethostname, buffer, size);
|
||||
|
@ -42,6 +42,7 @@ int fstat(int fd, struct stat* statbuf);
|
||||
int lstat(const char* path, struct stat* statbuf);
|
||||
int stat(const char* path, struct stat* statbuf);
|
||||
int sleep(unsigned seconds);
|
||||
int usleep(useconds_t);
|
||||
int gethostname(char*, size_t);
|
||||
ssize_t readlink(const char* path, char* buffer, size_t);
|
||||
char* ttyname(int fd);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Terminal.h"
|
||||
#include "XtermColors.h"
|
||||
#include <AK/AKString.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <SharedGraphics/Font.h>
|
||||
@ -72,12 +73,12 @@ Terminal::Line::~Line()
|
||||
delete [] attributes;
|
||||
}
|
||||
|
||||
void Terminal::Line::clear()
|
||||
void Terminal::Line::clear(Attribute attribute)
|
||||
{
|
||||
dirty = true;
|
||||
memset(characters, ' ', length);
|
||||
for (word i = 0 ; i < length; ++i)
|
||||
attributes[i].reset();
|
||||
attributes[i] = attribute;
|
||||
}
|
||||
|
||||
Terminal::~Terminal()
|
||||
@ -91,7 +92,7 @@ Terminal::~Terminal()
|
||||
void Terminal::clear()
|
||||
{
|
||||
for (size_t i = 0; i < rows(); ++i)
|
||||
line(i).clear();
|
||||
line(i).clear(m_current_attribute);
|
||||
set_cursor(0, 0);
|
||||
}
|
||||
|
||||
@ -125,50 +126,22 @@ unsigned parse_uint(const String& str, bool& ok)
|
||||
return value;
|
||||
}
|
||||
|
||||
enum ANSIColor : byte {
|
||||
Black = 0,
|
||||
Red,
|
||||
Green,
|
||||
Brown,
|
||||
Blue,
|
||||
Magenta,
|
||||
Cyan,
|
||||
LightGray,
|
||||
DarkGray,
|
||||
BrightRed,
|
||||
BrightGreen,
|
||||
Yellow,
|
||||
BrightBlue,
|
||||
BrightMagenta,
|
||||
BrightCyan,
|
||||
White,
|
||||
};
|
||||
|
||||
static inline Color ansi_color(unsigned color)
|
||||
static inline Color lookup_color(unsigned color)
|
||||
{
|
||||
static const RGBA32 s_ansi_color[16] = {
|
||||
make_rgb(0, 0, 0), // Black
|
||||
make_rgb(225, 56, 43), // Red
|
||||
make_rgb(57, 181, 74), // Green
|
||||
make_rgb(255, 199, 6), // Brown
|
||||
make_rgb(0, 111, 184), // Blue
|
||||
make_rgb(118, 38, 113), // Magenta
|
||||
make_rgb(44, 181, 233), // Cyan
|
||||
make_rgb(204, 204, 204), // LightGray
|
||||
make_rgb(128, 128, 128), // DarkGray
|
||||
make_rgb(255, 0, 0), // BrightRed
|
||||
make_rgb(0, 255, 0), // BrightGreen
|
||||
make_rgb(255, 255, 0), // Yellow
|
||||
make_rgb(0, 0, 255), // BrightBlue
|
||||
make_rgb(255, 0, 255), // BrightMagenta
|
||||
make_rgb(0, 255, 255), // BrightCyan
|
||||
make_rgb(255, 255, 255), // White
|
||||
};
|
||||
return s_ansi_color[color];
|
||||
return xterm_colors[color];
|
||||
}
|
||||
|
||||
void Terminal::escape$m(const Vector<unsigned>& params)
|
||||
{
|
||||
if (params.size() == 3 && params[1] == 5) {
|
||||
if (params[0] == 38) {
|
||||
m_current_attribute.foreground_color = params[2];
|
||||
return;
|
||||
} else if (params[0] == 48) {
|
||||
m_current_attribute.background_color = params[2];
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto param : params) {
|
||||
switch (param) {
|
||||
case 0:
|
||||
@ -364,6 +337,8 @@ void Terminal::execute_xterm_command()
|
||||
if (ok) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
set_window_title(String((const char*)m_xterm_param2.data(), m_xterm_param2.size()));
|
||||
break;
|
||||
default:
|
||||
@ -384,6 +359,8 @@ void Terminal::execute_escape_sequence(byte final)
|
||||
bool ok;
|
||||
unsigned value = parse_uint(parampart, ok);
|
||||
if (!ok) {
|
||||
m_parameters.clear_with_capacity();
|
||||
m_intermediates.clear_with_capacity();
|
||||
// FIXME: Should we do something else?
|
||||
return;
|
||||
}
|
||||
@ -406,8 +383,8 @@ void Terminal::execute_escape_sequence(byte final)
|
||||
break;
|
||||
}
|
||||
|
||||
m_parameters.clear();
|
||||
m_intermediates.clear();
|
||||
m_parameters.clear_with_capacity();
|
||||
m_intermediates.clear_with_capacity();
|
||||
}
|
||||
|
||||
void Terminal::newline()
|
||||
@ -463,7 +440,7 @@ void Terminal::put_character_at(unsigned row, unsigned column, byte ch)
|
||||
void Terminal::on_char(byte ch)
|
||||
{
|
||||
#ifdef TERMINAL_DEBUG
|
||||
dbgprintf("Terminal::on_char: %b (%c)\n", ch, ch);
|
||||
dbgprintf("Terminal::on_char: %b (%c), fg=%u, bg=%u\n", ch, ch, m_current_attribute.foreground_color, m_current_attribute.background_color);
|
||||
#endif
|
||||
switch (m_escape_state) {
|
||||
case ExpectBracket:
|
||||
@ -617,14 +594,9 @@ Rect Terminal::glyph_rect(word row, word column)
|
||||
Rect Terminal::row_rect(word row)
|
||||
{
|
||||
int y = row * m_line_height;
|
||||
return { m_inset, y + m_inset, font().glyph_width() * m_columns, font().glyph_height() };
|
||||
}
|
||||
|
||||
inline Terminal::Attribute& Terminal::attribute_at(word row, word column)
|
||||
{
|
||||
ASSERT(row < m_rows);
|
||||
ASSERT(column < m_columns);
|
||||
return line(row).attributes[column];
|
||||
Rect rect = { m_inset, y + m_inset, font().glyph_width() * m_columns, font().glyph_height() };
|
||||
rect.inflate(0, m_line_spacing);
|
||||
return rect;
|
||||
}
|
||||
|
||||
bool Terminal::Line::has_only_one_background_color() const
|
||||
@ -671,25 +643,29 @@ void Terminal::paint()
|
||||
continue;
|
||||
line.dirty = false;
|
||||
bool has_only_one_background_color = line.has_only_one_background_color();
|
||||
if (has_only_one_background_color)
|
||||
painter.fill_rect(row_rect(row), line.attributes[0].background_color);
|
||||
if (has_only_one_background_color) {
|
||||
painter.fill_rect(row_rect(row), lookup_color(line.attributes[0].background_color));
|
||||
}
|
||||
for (word column = 0; column < m_columns; ++column) {
|
||||
bool should_reverse_fill_for_cursor = m_in_active_window && row == m_cursor_row && column == m_cursor_column;
|
||||
auto& attribute = line.attributes[column];
|
||||
line.did_paint = true;
|
||||
char ch = line.characters[column];
|
||||
auto character_rect = glyph_rect(row, column);
|
||||
if (!has_only_one_background_color || should_reverse_fill_for_cursor)
|
||||
painter.fill_rect(character_rect, ansi_color(should_reverse_fill_for_cursor ? attribute.foreground_color : attribute.background_color));
|
||||
if (!has_only_one_background_color || should_reverse_fill_for_cursor) {
|
||||
auto cell_rect = character_rect;
|
||||
cell_rect.inflate(0, m_line_spacing);
|
||||
painter.fill_rect(cell_rect, lookup_color(should_reverse_fill_for_cursor ? attribute.foreground_color : attribute.background_color));
|
||||
}
|
||||
if (ch == ' ')
|
||||
continue;
|
||||
painter.draw_glyph(character_rect.location(), ch, ansi_color(should_reverse_fill_for_cursor ? attribute.background_color : attribute.foreground_color));
|
||||
painter.draw_glyph(character_rect.location(), ch, lookup_color(should_reverse_fill_for_cursor ? attribute.background_color : attribute.foreground_color));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_in_active_window) {
|
||||
auto cursor_rect = glyph_rect(m_cursor_row, m_cursor_column);
|
||||
painter.draw_rect(cursor_rect, ansi_color(line(m_cursor_row).attributes[m_cursor_column].foreground_color));
|
||||
painter.draw_rect(cursor_rect, lookup_color(line(m_cursor_row).attributes[m_cursor_column].foreground_color));
|
||||
}
|
||||
|
||||
line(m_cursor_row).did_paint = true;
|
||||
|
@ -63,8 +63,8 @@ private:
|
||||
background_color = 0;
|
||||
//bold = false;
|
||||
}
|
||||
unsigned foreground_color : 4;
|
||||
unsigned background_color : 4;
|
||||
byte foreground_color;
|
||||
byte background_color;
|
||||
//bool bold : 1;
|
||||
bool operator==(const Attribute& other) const
|
||||
{
|
||||
@ -75,7 +75,7 @@ private:
|
||||
struct Line {
|
||||
explicit Line(word columns);
|
||||
~Line();
|
||||
void clear();
|
||||
void clear(Attribute);
|
||||
bool has_only_one_background_color() const;
|
||||
byte* characters { nullptr };
|
||||
Attribute* attributes { nullptr };
|
||||
@ -98,8 +98,6 @@ private:
|
||||
|
||||
Attribute m_current_attribute;
|
||||
|
||||
Attribute& attribute_at(word row, word column);
|
||||
|
||||
void execute_escape_sequence(byte final);
|
||||
void execute_xterm_command();
|
||||
|
||||
|
260
Terminal/XtermColors.h
Normal file
260
Terminal/XtermColors.h
Normal file
@ -0,0 +1,260 @@
|
||||
#pragma once
|
||||
|
||||
static const unsigned xterm_colors[256] = {
|
||||
0x000000,
|
||||
0xcc0000,
|
||||
0x3e9a06,
|
||||
0xc4a000,
|
||||
0x3465a4,
|
||||
0x75507b,
|
||||
0x06989a,
|
||||
0xeeeeec,
|
||||
0x555753,
|
||||
0xef2929,
|
||||
0x8ae234,
|
||||
0xfce94f,
|
||||
0x729fcf,
|
||||
0xad7fa8,
|
||||
0x34e2e2,
|
||||
0xFFFFFF,
|
||||
0x000000,
|
||||
0x00005f,
|
||||
0x000087,
|
||||
0x0000af,
|
||||
0x0000d7,
|
||||
0x0000ff,
|
||||
0x005f00,
|
||||
0x005f5f,
|
||||
0x005f87,
|
||||
0x005faf,
|
||||
0x005fd7,
|
||||
0x005fff,
|
||||
0x008700,
|
||||
0x00875f,
|
||||
0x008787,
|
||||
0x0087af,
|
||||
0x0087d7,
|
||||
0x0087ff,
|
||||
0x00af00,
|
||||
0x00af5f,
|
||||
0x00af87,
|
||||
0x00afaf,
|
||||
0x00afd7,
|
||||
0x00afff,
|
||||
0x00d700,
|
||||
0x00d75f,
|
||||
0x00d787,
|
||||
0x00d7af,
|
||||
0x00d7d7,
|
||||
0x00d7ff,
|
||||
0x00ff00,
|
||||
0x00ff5f,
|
||||
0x00ff87,
|
||||
0x00ffaf,
|
||||
0x00ffd7,
|
||||
0x00ffff,
|
||||
0x5f0000,
|
||||
0x5f005f,
|
||||
0x5f0087,
|
||||
0x5f00af,
|
||||
0x5f00d7,
|
||||
0x5f00ff,
|
||||
0x5f5f00,
|
||||
0x5f5f5f,
|
||||
0x5f5f87,
|
||||
0x5f5faf,
|
||||
0x5f5fd7,
|
||||
0x5f5fff,
|
||||
0x5f8700,
|
||||
0x5f875f,
|
||||
0x5f8787,
|
||||
0x5f87af,
|
||||
0x5f87d7,
|
||||
0x5f87ff,
|
||||
0x5faf00,
|
||||
0x5faf5f,
|
||||
0x5faf87,
|
||||
0x5fafaf,
|
||||
0x5fafd7,
|
||||
0x5fafff,
|
||||
0x5fd700,
|
||||
0x5fd75f,
|
||||
0x5fd787,
|
||||
0x5fd7af,
|
||||
0x5fd7d7,
|
||||
0x5fd7ff,
|
||||
0x5fff00,
|
||||
0x5fff5f,
|
||||
0x5fff87,
|
||||
0x5fffaf,
|
||||
0x5fffd7,
|
||||
0x5fffff,
|
||||
0x870000,
|
||||
0x87005f,
|
||||
0x870087,
|
||||
0x8700af,
|
||||
0x8700d7,
|
||||
0x8700ff,
|
||||
0x875f00,
|
||||
0x875f5f,
|
||||
0x875f87,
|
||||
0x875faf,
|
||||
0x875fd7,
|
||||
0x875fff,
|
||||
0x878700,
|
||||
0x87875f,
|
||||
0x878787,
|
||||
0x8787af,
|
||||
0x8787d7,
|
||||
0x8787ff,
|
||||
0x87af00,
|
||||
0x87af5f,
|
||||
0x87af87,
|
||||
0x87afaf,
|
||||
0x87afd7,
|
||||
0x87afff,
|
||||
0x87d700,
|
||||
0x87d75f,
|
||||
0x87d787,
|
||||
0x87d7af,
|
||||
0x87d7d7,
|
||||
0x87d7ff,
|
||||
0x87ff00,
|
||||
0x87ff5f,
|
||||
0x87ff87,
|
||||
0x87ffaf,
|
||||
0x87ffd7,
|
||||
0x87ffff,
|
||||
0xaf0000,
|
||||
0xaf005f,
|
||||
0xaf0087,
|
||||
0xaf00af,
|
||||
0xaf00d7,
|
||||
0xaf00ff,
|
||||
0xaf5f00,
|
||||
0xaf5f5f,
|
||||
0xaf5f87,
|
||||
0xaf5faf,
|
||||
0xaf5fd7,
|
||||
0xaf5fff,
|
||||
0xaf8700,
|
||||
0xaf875f,
|
||||
0xaf8787,
|
||||
0xaf87af,
|
||||
0xaf87d7,
|
||||
0xaf87ff,
|
||||
0xafaf00,
|
||||
0xafaf5f,
|
||||
0xafaf87,
|
||||
0xafafaf,
|
||||
0xafafd7,
|
||||
0xafafff,
|
||||
0xafd700,
|
||||
0xafd75f,
|
||||
0xafd787,
|
||||
0xafd7af,
|
||||
0xafd7d7,
|
||||
0xafd7ff,
|
||||
0xafff00,
|
||||
0xafff5f,
|
||||
0xafff87,
|
||||
0xafffaf,
|
||||
0xafffd7,
|
||||
0xafffff,
|
||||
0xd70000,
|
||||
0xd7005f,
|
||||
0xd70087,
|
||||
0xd700af,
|
||||
0xd700d7,
|
||||
0xd700ff,
|
||||
0xd75f00,
|
||||
0xd75f5f,
|
||||
0xd75f87,
|
||||
0xd75faf,
|
||||
0xd75fd7,
|
||||
0xd75fff,
|
||||
0xd78700,
|
||||
0xd7875f,
|
||||
0xd78787,
|
||||
0xd787af,
|
||||
0xd787d7,
|
||||
0xd787ff,
|
||||
0xd7af00,
|
||||
0xd7af5f,
|
||||
0xd7af87,
|
||||
0xd7afaf,
|
||||
0xd7afd7,
|
||||
0xd7afff,
|
||||
0xd7d700,
|
||||
0xd7d75f,
|
||||
0xd7d787,
|
||||
0xd7d7af,
|
||||
0xd7d7d7,
|
||||
0xd7d7ff,
|
||||
0xd7ff00,
|
||||
0xd7ff5f,
|
||||
0xd7ff87,
|
||||
0xd7ffaf,
|
||||
0xd7ffd7,
|
||||
0xd7ffff,
|
||||
0xff0000,
|
||||
0xff005f,
|
||||
0xff0087,
|
||||
0xff00af,
|
||||
0xff00d7,
|
||||
0xff00ff,
|
||||
0xff5f00,
|
||||
0xff5f5f,
|
||||
0xff5f87,
|
||||
0xff5faf,
|
||||
0xff5fd7,
|
||||
0xff5fff,
|
||||
0xff8700,
|
||||
0xff875f,
|
||||
0xff8787,
|
||||
0xff87af,
|
||||
0xff87d7,
|
||||
0xff87ff,
|
||||
0xffaf00,
|
||||
0xffaf5f,
|
||||
0xffaf87,
|
||||
0xffafaf,
|
||||
0xffafd7,
|
||||
0xffafff,
|
||||
0xffd700,
|
||||
0xffd75f,
|
||||
0xffd787,
|
||||
0xffd7af,
|
||||
0xffd7d7,
|
||||
0xffd7ff,
|
||||
0xffff00,
|
||||
0xffff5f,
|
||||
0xffff87,
|
||||
0xffffaf,
|
||||
0xffffd7,
|
||||
0xffffff,
|
||||
0x080808,
|
||||
0x121212,
|
||||
0x1c1c1c,
|
||||
0x262626,
|
||||
0x303030,
|
||||
0x3a3a3a,
|
||||
0x444444,
|
||||
0x4e4e4e,
|
||||
0x585858,
|
||||
0x626262,
|
||||
0x6c6c6c,
|
||||
0x767676,
|
||||
0x808080,
|
||||
0x8a8a8a,
|
||||
0x949494,
|
||||
0x9e9e9e,
|
||||
0xa8a8a8,
|
||||
0xb2b2b2,
|
||||
0xbcbcbc,
|
||||
0xc6c6c6,
|
||||
0xd0d0d0,
|
||||
0xdadada,
|
||||
0xe4e4e4,
|
||||
0xeeeeee,
|
||||
};
|
Loading…
Reference in New Issue
Block a user