A lot of refactoring

This commit is contained in:
Kevin Lange 2012-09-07 20:17:00 -07:00
parent 12bf07364c
commit af6be648d4
8 changed files with 211 additions and 145 deletions

1
hdd/usr/share/snowman Normal file
View File

@ -0,0 +1 @@

View File

@ -15,7 +15,7 @@ char * __kernel_version_format = "%d.%d.%d-%s";
/* Version numbers X.Y.Z */
int __kernel_version_major = 0;
int __kernel_version_minor = 2;
int __kernel_version_lower = 1;
int __kernel_version_lower = 3;
/* Kernel build suffix, which doesn't necessarily
* mean anything, but can be used to distinguish

View File

@ -17,6 +17,11 @@ uint16_t * file_buffer;
size_t file_len_unicode;
size_t file_len_available;
static struct _env {
int width;
int height;
} environment;
uint32_t codepoint;
uint32_t state = 0;
@ -66,6 +71,11 @@ int main(int argc, char * argv[]) {
return 1;
}
printf("\033[1003z");
fflush(stdout);
scanf("%d,%d", &environment.width, &environment.height);
printf("Terminal is %dx%d\n", environment.width, environment.height);
size_t length;
fseek(f, 0, SEEK_END);

View File

@ -521,18 +521,13 @@ void teardown_windowing () {
while ((node = list_pop(process_windows->windows)) != NULL) {
window = node->value;
if (!window) break;
printf("Have a window [%d, %dx%d]\n", window->wid, window->width, window->height);
window_destroy(window);
printf("Window destroy signal sent.\n");
}
printf("Freeing data...\n");
free(process_windows->windows);
printf("Freeing some more data...\n");
free(process_windows);
process_windows = NULL;
}
printf("Disconnecting...\n");
wins_disconnect();
}

7
userspace/setscale.c Normal file
View File

@ -0,0 +1,7 @@
#include <stdio.h>
int main(int argc, char ** argv) {
printf("\033[1555;%sz", argv[1]);
fflush(stdout);
return 0;
}

9
userspace/shutdown.c Normal file
View File

@ -0,0 +1,9 @@
#include <stdio.h>
#include <stdint.h>
int main(int argc, char * argv[]) {
printf("Shutting down...\n");
/* Nothing to actually do for shutdown, sadly */
__asm__ __volatile__ ("outw %1, %0" : : "dN" ((uint16_t)0xB004), "a" ((uint16_t)0x2000));
return 0;
}

View File

@ -37,50 +37,62 @@
#include "terminal-palette.h"
#include "terminal-font.h"
/* A terminal cell represents a single character on screen */
typedef struct _terminal_cell {
uint16_t c;
uint8_t fg;
uint8_t bg;
uint8_t flags;
uint16_t c; /* codepoint */
uint8_t fg; /* background indexed color */
uint8_t bg; /* foreground indexed color */
uint8_t flags; /* other flags */
} __attribute__((packed)) t_cell;
#define MOUSE_SCALE 6
/* The input and output descriptors for the child process;
* we read from ofd and write to ifd, so make sure you don't
* get them backwards. */
static int ofd, ifd;
static int ofd, ifd;
uint16_t term_width = 0;
uint16_t term_height = 0;
uint16_t font_size = 13;
uint16_t char_width = 8;
uint16_t char_height = 12;
uint16_t char_offset = 0;
uint16_t csr_x = 0;
uint16_t csr_y = 0;
t_cell * term_buffer = NULL;
uint8_t current_fg = 7;
uint8_t current_bg = 0;
uint16_t current_scroll = 0;
uint8_t cursor_on = 1;
window_t * window = NULL;
int _windowed = 0;
int _vga_mode = 0;
int _login_shell = 0;
int scale_fonts = 0; /* Whether fonts should be scaled */
float font_scaling = 1.0; /* How much they should be scaled by */
uint16_t term_width = 0; /* Width of the terminal (in cells) */
uint16_t term_height = 0; /* Height of the terminal (in cells) */
uint16_t font_size = 13; /* Font size according to Freetype */
uint16_t char_width = 8; /* Width of a cell in pixels */
uint16_t char_height = 12; /* Height of a cell in pixels */
uint16_t char_offset = 0; /* Offset of the font within the cell */
uint16_t csr_x = 0; /* Cursor X */
uint16_t csr_y = 0; /* Cursor Y */
t_cell * term_buffer = NULL; /* The terminal cell buffer */
uint8_t current_fg = 7; /* Current foreground color */
uint8_t current_bg = 0; /* Current background color */
uint8_t cursor_on = 1; /* Whether or not the cursor should be rendered */
window_t * window = NULL; /* GUI window */
int _windowed = 0; /* Whether or not we are running in the GUI enviornment */
int _vga_mode = 0; /* Whether or not we are in VGA mode XXX should be combined ^ */
int _login_shell = 0; /* Whether we're going to display a login shell or not */
uint8_t _use_freetype = 0; /* Whether we should use freetype or not XXX seriously, how about some flags */
void reinit(); /* Defined way further down */
/* Cursor bink timer */
static unsigned int timer_tick = 0;
#define TIMER_TICK 400000
/* Mouse control */
#define MOUSE_SCALE 6
int32_t mouse_x;
int32_t mouse_y;
/* Some GUI-only options */
uint16_t window_width = 640;
uint16_t window_height = 408;
#define TERMINAL_TITLE_SIZE 512
char terminal_title[TERMINAL_TITLE_SIZE];
size_t terminal_title_length = 0;
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 408
gfx_context_t * ctx;
volatile int needs_redraw = 1;
static void render_decors();
/* Trigger to exit the terminal when the child process dies or
* we otherwise receive an exit signal */
volatile int exit_application = 0;
/* Triggers escape mode. */
@ -125,26 +137,23 @@ volatile int exit_application = 0;
#define DEFAULT_BG 0x10
#define DEFAULT_FLAGS 0x00
#define ANSI_EXT_IOCTL 'z'
#define ANSI_EXT_IOCTL 'z' /* These are special escapes only we support */
/* Returns the lower of two shorts */
uint16_t min(uint16_t a, uint16_t b) {
return (a < b) ? a : b;
}
/* Returns the higher of two shorts */
uint16_t max(uint16_t a, uint16_t b) {
return (a > b) ? a : b;
}
/* Performs low-level port I/O; used for VGA initialization */
void outb(unsigned char _data, unsigned short _port) {
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
void input_buffer_stuff(char * str) {
size_t s = strlen(str);
write(ifd, str, s);
}
uint8_t _use_freetype = 0;
/* State machine status */
static struct _ansi_state {
uint16_t x ; /* Current cursor location */
@ -170,22 +179,25 @@ int (*ansi_get_csr_y)(void) = NULL;
void (*ansi_set_cell)(int,int,uint16_t) = NULL;
void (*ansi_cls)(void) = NULL;
/* XXX: Needs verification, but I'm pretty sure this never gets called */
void (*redraw_cursor)(void) = NULL;
int32_t mouse_x;
int32_t mouse_y;
/* Stuffs a string into the stdin of the terminal's child process
* Useful for things like the ANSI DSR command. */
void input_buffer_stuff(char * str) {
size_t s = strlen(str);
write(ifd, str, s);
}
void
ansi_dump_buffer() {
/* Write the contents of the buffer, as they were all non-escaped data. */
void ansi_dump_buffer() {
for (int i = 0; i < state.buflen; ++i) {
ansi_writer(state.buffer[i]);
}
}
void
ansi_buf_add(
char c
) {
/* Add to the internal buffer for the ANSI parser */
void ansi_buf_add(char c) {
state.buffer[state.buflen] = c;
state.buflen++;
state.buffer[state.buflen] = '\0';
@ -268,6 +280,13 @@ ansi_put(
input_buffer_stuff(out);
}
break;
case 1555:
if (argc > 1) {
printf("Setting scaling to %s\n", argv[1]);
scale_fonts = 1;
font_scaling = atof(argv[1]);
reinit();
}
default:
break;
}
@ -505,8 +524,9 @@ ansi_put(
}
}
void
ansi_init(void (*writer)(char), int w, int y, void (*setcolor)(unsigned char, unsigned char), void (*setcsr)(int,int), int (*getcsrx)(void), int (*getcsry)(void), void (*setcell)(int,int,uint16_t), void (*cls)(void), void (*redraw_csr)(void)) {
void ansi_init(void (*writer)(char), int w, int y, void (*setcolor)(unsigned char, unsigned char),
void (*setcsr)(int,int), int (*getcsrx)(void), int (*getcsry)(void), void (*setcell)(int,int,uint16_t),
void (*cls)(void), void (*redraw_csr)(void)) {
ansi_writer = writer;
ansi_set_color = setcolor;
@ -528,8 +548,7 @@ ansi_init(void (*writer)(char), int w, int y, void (*setcolor)(unsigned char, un
ansi_set_color(state.fg, state.bg);
}
void
ansi_print(char * c) {
void ansi_print(char * c) {
uint32_t len = strlen(c);
for (uint32_t i = 0; i < len; ++i) {
ansi_put(c[i]);
@ -546,25 +565,22 @@ static void render_decors() {
}
}
static inline void
term_set_point(
uint16_t x,
uint16_t y,
uint32_t color
) {
if (_windowed) {
GFX(ctx, (x+decor_left_width),(y+decor_top_height)) = color;
} else {
if (ctx->depth == 32) {
GFX(ctx, x,y) = color;
} else if (ctx->depth == 24) {
ctx->backbuffer[((y) * ctx->width + x) * 3 + 2] = _RED(color);
ctx->backbuffer[((y) * ctx->width + x) * 3 + 1] = _GRE(color);
ctx->backbuffer[((y) * ctx->width + x) * 3 + 0] = _BLU(color);
}
static inline void term_set_point(uint16_t x, uint16_t y, uint32_t color ) {
if (_windowed) {
GFX(ctx, (x+decor_left_width),(y+decor_top_height)) = color;
} else {
if (ctx->depth == 32) {
GFX(ctx, x,y) = color;
} else if (ctx->depth == 24) {
ctx->backbuffer[((y) * ctx->width + x) * 3 + 2] = _RED(color);
ctx->backbuffer[((y) * ctx->width + x) * 3 + 1] = _GRE(color);
ctx->backbuffer[((y) * ctx->width + x) * 3 + 0] = _BLU(color);
}
}
}
/* FreeType text rendering */
FT_Library library;
FT_Face face;
FT_Face face_bold;
@ -580,7 +596,6 @@ void drawChar(FT_Bitmap * bitmap, int x, int y, uint32_t fg, uint32_t bg) {
int y_max = y + bitmap->rows;
for (j = y, q = 0; j < y_max; j++, q++) {
for ( i = x, p = 0; i < x_max; i++, p++) {
//GFX(ctx, i,j) = alpha_blend(GFX(ctx, i,j),rgb(0xff,0xff,0xff),rgb(bitmap->buffer[q * bitmap->width + p],0,0));
term_set_point(i,j, alpha_blend(bg, fg, rgb(bitmap->buffer[q * bitmap->width + p],0,0)));
}
}
@ -594,6 +609,7 @@ void placech(unsigned char c, int x, int y, int attr) {
*where = c | att;
}
/* ANSI-to-VGA */
char vga_to_ansi[] = {
0, 4, 2, 6, 1, 5, 3, 7,
8,12,10,14, 9,13,11,15
@ -1034,13 +1050,6 @@ void * wait_for_exit(void * garbage) {
/* Exit */
}
void waitabit() {
int x = time(NULL);
while (time(NULL) < x + 1) {
// Do nothing.
}
}
void usage(char * argv[]) {
printf(
"Terminal Emulator\n"
@ -1050,12 +1059,76 @@ void usage(char * argv[]) {
" -F --fullscreen \033[3mRun in legacy fullscreen mode.\033[0m\n"
" -b --bitmap \033[3mUse the integrated bitmap font.\033[0m\n"
" -h --help \033[3mShow this help message.\033[0m\n"
" -s --scale \033[3mScale the font in FreeType mode by a given amount.\033[0m\n"
"\n"
" This terminal emulator provides basic support for VT220 escapes and\n"
" XTerm extensions, including 256 color support and font effects.\n",
argv[0]);
}
void reinit() {
if (_use_freetype) {
/* Reset font sizes */
font_size = 13;
char_height = 17;
char_width = 8;
char_offset = 13;
if (scale_fonts) {
/* Recalculate scaling */
font_size *= font_scaling;
char_height *= font_scaling;
char_width *= font_scaling;
char_offset *= font_scaling;
}
/* Initialize the freetype font pixel sizes */
FT_Set_Pixel_Sizes(face, font_size, font_size);
FT_Set_Pixel_Sizes(face_bold, font_size, font_size);
FT_Set_Pixel_Sizes(face_italic, font_size, font_size);
FT_Set_Pixel_Sizes(face_bold_italic, font_size, font_size);
FT_Set_Pixel_Sizes(face_extra, font_size, font_size);
}
if (_windowed) {
term_width = window_width / char_width;
term_height = window_height / char_height;
} else if (_vga_mode) {
if (!ctx) {
/* This is only set so that the mouse scaling has only one code-path
* so reallocating this for resizes is pointless as VGA mode will never
* change its sizes. */
ctx = malloc(sizeof(gfx_context_t));
ctx->width = 800;
ctx->height = 250;
}
/* Set the actual terminal size */
term_width = 80;
term_height = 25;
/* Set these to fake values, primarily for the mouse again */
char_width = 1;
char_height = 1;
} else {
/* Non-windowed graphical mode */
term_width = ctx->width / char_width;
term_height = ctx->height / char_height;
}
if (term_buffer) {
free(term_buffer);
}
/* XXX: Transfer values, cursor location, etc.? */
term_buffer = malloc(sizeof(t_cell) * term_width * term_height);
ansi_init(&term_write, term_width, term_height, &term_set_colors, &term_set_csr, &term_get_csr_x, &term_get_csr_y, &term_set_cell, &term_term_clear, &term_redraw_cursor);
mouse_x = ctx->width / 2;
mouse_y = ctx->height / 2;
/* A lot of this is probably uneccessary if we do some sort of resize... */
term_term_clear();
ansi_print("\033[H\033[2J");
}
int main(int argc, char ** argv) {
@ -1064,17 +1137,19 @@ int main(int argc, char ** argv) {
_login_shell = 0;
static struct option long_opts[] = {
{"fullscreen", no_argument, 0, 'F'},
{"bitmap", no_argument, 0, 'b'},
{"vga", no_argument, 0, 'V'},
{"login", no_argument, 0, 'l'},
{"help", no_argument, 0, 'h'},
{"fullscreen", no_argument, 0, 'F'},
{"bitmap", no_argument, 0, 'b'},
{"vga", no_argument, 0, 'V'},
{"login", no_argument, 0, 'l'},
{"help", no_argument, 0, 'h'},
{"scale", required_argument, 0, 's'},
{"geometry", required_argument, 0, 'g'},
{0,0,0,0}
};
/* Read some arguments */
int index, c;
while ((c = getopt_long(argc, argv, "bhFVl", long_opts, &index)) != -1) {
while ((c = getopt_long(argc, argv, "bhFVls:g:", long_opts, &index)) != -1) {
if (!c) {
if (long_opts[index].flag == 0) {
c = long_opts[index].val;
@ -1099,6 +1174,21 @@ int main(int argc, char ** argv) {
usage(argv);
return 0;
break;
case 's':
scale_fonts = 1;
font_scaling = atof(optarg);
break;
case 'g':
{
char * c = strstr(optarg, "x");
if (c) {
*c = '\0';
c++;
window_width = atoi(optarg);
window_width = atoi(c);
}
}
break;
case '?':
break;
default:
@ -1107,34 +1197,24 @@ int main(int argc, char ** argv) {
}
if (_windowed) {
/* Initialize the windowing library */
setup_windowing();
waitabit();
int x = 20, y = 20;
#if 0
if (index < argc) {
x = atoi(argv[index]);
printf("Window offset x = %d\n", x);
index++;
}
if (index < argc) {
y = atoi(argv[index]);
printf("Window offset y = %d\n", y);
index++;
}
#endif
printf("Decorations are %d %d %d %d\n", decor_top_height, decor_right_width, decor_bottom_height, decor_left_width);
window = window_create(x,y, WINDOW_WIDTH + decor_left_width + decor_right_width, WINDOW_HEIGHT + decor_top_height + decor_bottom_height);
printf("Have a window! %p\n", window);
/* Create the window */
window = window_create(x,y, window_width + decor_left_width + decor_right_width, window_height + decor_top_height + decor_bottom_height);
/* Initialize the decoration library */
init_decorations();
render_decors();
/* Initialize the graphics context */
ctx = init_graphics_window(window);
/* Clear to black */
draw_fill(ctx, rgb(0,0,0));
} else if (_vga_mode) {
/* Herp derp? */
/* Set some important VGA options */
int temp = 0xFFFF;
outb(14, 0x3D4);
outb(temp >> 8, 0x3D5);
@ -1158,73 +1238,32 @@ int main(int argc, char ** argv) {
setLoaded(3,0);
setLoaded(4,0);
#ifndef BIG_FONTS
font_size = 13;
char_height = 17;
char_width = 8;
char_offset = 13;
#else
font_size = 26;
char_height = 34;
char_width = 16;
char_offset = 26;
#endif
setLoaded(0,2);
font = loadMemFont("/usr/share/fonts/DejaVuSansMono.ttf", WINS_SERVER_IDENTIFIER ".fonts.monospace", &s);
error = FT_New_Memory_Face(library, font, s, 0, &face); if (error) return 1;
error = FT_Set_Pixel_Sizes(face, font_size, font_size); if (error) return 1;
setLoaded(0,1);
setLoaded(1,2);
font = loadMemFont("/usr/share/fonts/DejaVuSansMono-Bold.ttf", WINS_SERVER_IDENTIFIER ".fonts.monospace.bold", &s);
error = FT_New_Memory_Face(library, font, s, 0, &face_bold); if (error) return 1;
error = FT_Set_Pixel_Sizes(face_bold, font_size, font_size); if (error) return 1;
setLoaded(1,1);
setLoaded(2,2);
font = loadMemFont("/usr/share/fonts/DejaVuSansMono-Oblique.ttf", WINS_SERVER_IDENTIFIER ".fonts.monospace.italic", &s);
error = FT_New_Memory_Face(library, font, s, 0, &face_italic); if (error) return 1;
error = FT_Set_Pixel_Sizes(face_italic, font_size, font_size); if (error) return 1;
setLoaded(2,1);
setLoaded(3,2);
font = loadMemFont("/usr/share/fonts/DejaVuSansMono-BoldOblique.ttf", WINS_SERVER_IDENTIFIER ".fonts.monospace.bolditalic", &s);
error = FT_New_Memory_Face(library, font, s, 0, &face_bold_italic); if (error) return 1;
error = FT_Set_Pixel_Sizes(face_bold_italic, font_size, font_size); if (error) return 1;
setLoaded(3,1);
setLoaded(4,2);
error = FT_New_Face(library, "/usr/share/fonts/VLGothic.ttf", 0, &face_extra);
error = FT_Set_Pixel_Sizes(face_extra, font_size, font_size); if (error) return 1;
setLoaded(4,1);
}
if (_windowed) {
term_width = WINDOW_WIDTH / char_width;
term_height = WINDOW_HEIGHT / char_height;
} else if (_vga_mode) {
ctx = malloc(sizeof(gfx_context_t));
ctx->width = 800;
ctx->height = 250;
term_width = 80;
term_height = 25;
char_width = 1;
char_height = 1;
} else {
term_width = ctx->width / char_width;
term_height = ctx->height / char_height;
}
term_buffer = malloc(sizeof(t_cell) * term_width * term_height);
ansi_init(&term_write, term_width, term_height, &term_set_colors, &term_set_csr, &term_get_csr_x, &term_get_csr_y, &term_set_cell, &term_term_clear, &term_redraw_cursor);
mouse_x = ctx->width / 2;
mouse_y = ctx->height / 2;
term_term_clear();
ansi_print("\033[H\033[2J");
reinit();
ofd = syscall_mkpipe();
ifd = syscall_mkpipe();

View File

@ -8,6 +8,7 @@ FULLSCREEN=false
ENABLE_SERIAL=true
ENABLE_GRAPHICS=true
BORDERLESS=true
SINGLE=false
# Load the config file
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
@ -42,5 +43,9 @@ if [ $BORDERLESS == false ]; then
BORDERS=""
fi
if [ $SINGLE == true ]; then
GRAPHICS="$GRAPHICS single"
fi
# Generate the QEMU arguments list
echo "-kernel toaruos-kernel -m $EMU_MEMORY $ENABLEKVM $FULL_SCREEN $SERIAL -vga std -hda toaruos-disk.img -k en-us $BORDERS -append \"$GRAPHICS hdd\""