diff --git a/apps/beep.c b/apps/beep.c new file mode 100644 index 00000000..aade3182 --- /dev/null +++ b/apps/beep.c @@ -0,0 +1,54 @@ +/* This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2014 K. Lange + */ +#include +#include +#include + +int spkr = 0; + +struct spkr { + int length; + int frequency; +}; + +void note(int length, int frequency) { + struct spkr s = { + .length = length, + .frequency = frequency, + }; + + write(spkr, &s, sizeof(s)); +} + +int main(int argc, char * argv[]) { + + spkr = open("/dev/spkr", O_WRONLY); + if (spkr == -1) { + fprintf(stderr, "%s: could not open speaker\n", argv[0]); + } + + note(20, 15680); + note(10, 11747); + note(10, 12445); + note(20, 13969); + note(10, 12445); + note(10, 11747); + note(20, 10465); + note(10, 10465); + note(10, 12445); + note(20, 15680); + note(10, 13969); + note(10, 12445); + note(30, 11747); + note(10, 12445); + note(20, 13969); + note(20, 15680); + note(20, 12445); + note(20, 10465); + note(20, 10465); + + return 0; +} + diff --git a/apps/cat-img.c b/apps/cat-img.c new file mode 100644 index 00000000..dbdb51be --- /dev/null +++ b/apps/cat-img.c @@ -0,0 +1,145 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2016-2018 K. Lange + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +void get_cell_sizes(int * w, int * h) { + struct winsize wsz; + ioctl(0, TIOCGWINSZ, &wsz); + + if (!wsz.ws_col || !wsz.ws_row) { + *w = 0; + *h = 0; + } + + *w = wsz.ws_xpixel / wsz.ws_col; + *h = wsz.ws_ypixel / wsz.ws_row; +} + +void raw_output(void) { + struct termios new; + tcgetattr(fileno(stdin), &new); + new.c_oflag &= (~ONLCR); + tcsetattr(fileno(stdin), TCSAFLUSH, &new); +} + +void unraw_output(void) { + struct termios new; + tcgetattr(fileno(stdin), &new); + new.c_oflag |= ONLCR; + tcsetattr(fileno(stdin), TCSAFLUSH, &new); +} + +int usage(char * argv[]) { + printf( + "usage: %s [-?ns] [path]\n" + "\n" + " -n \033[3mdon't print a new line after image\033[0m\n" + " -s \033[3mscale to cell height (up or down)\033[0m\n" + " -? \033[3mshow this help text\033[0m\n" + "\n", argv[0]); + return 1; +} + +int main (int argc, char * argv[]) { + if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { + fprintf(stderr, "Can't cat-img to a non-terminal.\n"); + exit(1); + } + + int opt; + int no_newline = 0; + int scale_to_cell_height = 0; + + while ((opt = getopt(argc, argv, "?ns")) != -1) { + switch (opt) { + case '?': + return usage(argv); + case 'n': + no_newline = 1; + break; + case 's': + scale_to_cell_height = 1; + break; + } + } + + if (optind >= argc ) { + return usage(argv); + } + + int w, h; + get_cell_sizes(&w, &h); + + if (!w || !h) return 1; + + while (optind < argc) { + sprite_t * image = calloc(sizeof(sprite_t),1); + load_sprite(image, argv[optind]); + + sprite_t * source = image; + + if (scale_to_cell_height) { + int new_width = (h * image->width) / image->height; + source = create_sprite(new_width,h,1); + gfx_context_t * g = init_graphics_sprite(source); + draw_fill(g, 0x00000000); + draw_sprite_scaled(g, image, 0, 0, new_width, h); + sprite_free(image); + } + + int width_in_cells = source->width / w; + if (source->width % w) width_in_cells++; + + int height_in_cells = source->height / h; + if (source->height % h) height_in_cells++; + + raw_output(); + printf("\033[?25l"); + + for (int y = 0; y < height_in_cells; y++) { + for (int x = 0; x < width_in_cells; x++) { + printf("\033Ts"); + uint32_t * tmp = malloc(sizeof(uint32_t) * w * h); + for (int yy = 0; yy < h; yy++) { + for (int xx = 0; xx < w; xx++) { + if (x*w + xx >= source->width || y*h + yy >= source->height) { + tmp[yy * w + xx] = rgba(0,0,0,TERM_DEFAULT_OPAC); + } else { + uint32_t data = alpha_blend_rgba( + rgba(0,0,0,TERM_DEFAULT_OPAC), + premultiply(source->bitmap[(x*w+xx)+(y*h+yy)*source->width])); + tmp[yy * w + xx] = data; + } + } + } + fwrite(tmp, sizeof(uint32_t) * w * h, 1, stdout); + free(tmp); + fflush(stdout); + } + if (y != height_in_cells - 1 || !no_newline) { + printf("\r\n"); + } + } + + sprite_free(source); + + printf("\033[?25h"); + unraw_output(); + fflush(stdout); + optind++; + } + + return 0; +} + diff --git a/apps/insmod.c b/apps/insmod.c new file mode 100644 index 00000000..3d22d979 --- /dev/null +++ b/apps/insmod.c @@ -0,0 +1,14 @@ +/* This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2016 K. Lange + */ +#include +#include + +int main(int argc, char * argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + return syscall_system_function(8, &argv[1]); +} diff --git a/apps/mixerctl.c b/apps/mixerctl.c new file mode 100644 index 00000000..b163adbf --- /dev/null +++ b/apps/mixerctl.c @@ -0,0 +1,124 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2015 Mike Gerow + */ + +#include +#include +#include +#include +#include + +#include + +static char usage[] = +"Usage %s [-d device_id] -l\n" +" %s [-d device_id] [-k knob_id] -r\n" +" %s [-d device_id] [-k knob_id] -w knob_value\n" +" %s -h\n" +" -d: Device id to address. Defaults to the main sound device.\n" +" -l: List the knobs on a device.\n" +" -k: Knob id to address. Defaults to the device's master knob.\n" +" -r: Perform a read on the given device's knob. Defaults to the device's\n" +" master knob.\n" +" -w: Perform a write on the given device's knob. The value should be a\n" +" float from 0.0 to 1.0.\n" +" -h: Print this help message and exit.\n"; + +int main(int argc, char * argv[]) { + uint32_t device_id = SND_DEVICE_MAIN; + uint32_t knob_id = SND_KNOB_MASTER; + uint8_t list_flag = 0; + uint8_t read_flag = 0; + uint8_t write_flag = 0; + double write_value = 0.0; + + int c; + + while ((c = getopt(argc, argv, "d:lk:rw:h")) != -1) { + switch (c) { + case 'd': + device_id = atoi(optarg); + break; + case 'l': + list_flag = 1; + break; + case 'k': + knob_id = atoi(optarg); + break; + case 'r': + read_flag = 1; + break; + case 'w': + write_flag = 1; + write_value = atof(optarg); + if (write_value < 0.0 || write_value > 1.0) { + fprintf(stderr, "argument -w value must be between 0.0 and 1.0\n"); + exit(EXIT_FAILURE); + } + break; + case 'h': + fprintf(stdout, usage, argv[0], argv[0], argv[0], argv[0]); + exit(EXIT_SUCCESS); + default: + fprintf(stderr, usage, argv[0], argv[0], argv[0], argv[0]); + exit(EXIT_FAILURE); + } + } + + int mixer = open("/dev/mixer", O_RDONLY); + if (mixer < 1) { + //perror("open"); + exit(EXIT_FAILURE); + } + + if (list_flag) { + snd_knob_list_t list = {0}; + list.device = device_id; + if (ioctl(mixer, SND_MIXER_GET_KNOBS, &list) < 0) { + perror("ioctl"); + exit(EXIT_FAILURE); + } + for (uint32_t i = 0; i < list.num; i++) { + snd_knob_info_t info = {0}; + info.device = device_id; + info.id = list.ids[i]; + if (ioctl(mixer, SND_MIXER_GET_KNOB_INFO, &info) < 0) { + perror("ioctl"); + exit(EXIT_FAILURE); + } + fprintf(stdout, "%d: %s\n", (unsigned int)info.id, info.name); + } + + exit(EXIT_SUCCESS); + } + + if (read_flag) { + snd_knob_value_t value = {0}; + value.device = device_id; + value.id = knob_id; + if (ioctl(mixer, SND_MIXER_READ_KNOB, &value) < 0) { + perror("ioctl"); + exit(EXIT_FAILURE); + } + double double_val = (double)value.val / SND_KNOB_MAX_VALUE; + fprintf(stdout, "%f\n", double_val); + exit(EXIT_FAILURE); + } + + if (write_flag) { + snd_knob_value_t value = {0}; + value.device = device_id; + value.id = knob_id; + value.val = (uint32_t)(write_value * SND_KNOB_MAX_VALUE); + if (ioctl(mixer, SND_MIXER_WRITE_KNOB, &value) < 0) { + perror("ioctl"); + exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); + } + + fprintf(stderr, "No operation specified.\n"); + exit(EXIT_FAILURE); +} diff --git a/apps/which.c b/apps/which.c index 9748885e..46aef190 100644 --- a/apps/which.c +++ b/apps/which.c @@ -1,6 +1,6 @@ /* This file is part of ToaruOS and is released under the terms * of the NCSA / University of Illinois License - see LICENSE.md - * Copyright (C) 2013-2014 Kevin Lange + * Copyright (C) 2013-2014 K. Lange * * which * diff --git a/base/usr/include/stdio.h b/base/usr/include/stdio.h index 55077c4e..48818191 100644 --- a/base/usr/include/stdio.h +++ b/base/usr/include/stdio.h @@ -42,3 +42,5 @@ extern char *fgets(char *s, int size, FILE *stream); extern void rewind(FILE *stream); extern void setbuf(FILE * stream, char * buf); + +extern void perror(const char *s); diff --git a/boot/cstuff.c b/boot/cstuff.c index 20718d84..10e6bbef 100644 --- a/boot/cstuff.c +++ b/boot/cstuff.c @@ -66,11 +66,12 @@ static char * modules[] = { "PCNET.KO", // 19 "RTL.KO", // 20 "E1000.KO", // 21 + "PCSPKR.KO", // 22 0 }; -static mboot_mod_t modules_mboot[23] = { +static mboot_mod_t modules_mboot[sizeof(modules)/sizeof(*modules)] = { {0,0,0,1} }; @@ -80,7 +81,7 @@ static struct multiboot multiboot_header = { /* mem_upper; */ 0x640000, /* boot_device; */ 0, /* cmdline; */ 0, - /* mods_count; */ 23, + /* mods_count; */ sizeof(modules)/sizeof(*modules), /* mods_addr; */ (uintptr_t)&modules_mboot, /* num; */ 0, /* size; */ 0, diff --git a/libc/stdio/perror.c b/libc/stdio/perror.c new file mode 100644 index 00000000..f05634ce --- /dev/null +++ b/libc/stdio/perror.c @@ -0,0 +1,6 @@ +#include +#include + +void perror(const char *s) { + fprintf(stderr, "%s: error %d\n", s, errno); +}