2023-05-21 22:19:48 +10:00

180 lines
4.3 KiB
C

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "quinn.h"
#include "convertxpm.h"
#include "sysfont.xpm"
int window_handle;
struct widget_t *listbox;
char *surf;
int depth = 4;
char font[4096];
char fontname[256];
struct quinn_dirent_t {
unsigned int name_len;
unsigned int rec_len;
unsigned int next_offset;
unsigned char type;
char name[1];
};
void exit_callback(int wh) {
quinn_exit();
exit(0);
}
void gui_putpixel(uint8_t *buffer, uint32_t dest_width, uint32_t dest_height, int x, int y, uint32_t color) {
if (x >= dest_width || y >= dest_height) {
return;
}
if (x < 0 || y < 0) {
return;
}
int where = (x * depth) + (y * dest_width * depth);
// alpha
buffer[where] = color & 255; // BLUE
buffer[where + 1] = (color >> 8) & 255; // GREEN
buffer[where + 2] = (color >> 16) & 255; // RED
buffer[where + 3] = 0xFF;
}
void gui_draw_char(uint8_t *buffer, uint32_t dest_width, uint32_t dest_height, uint32_t x, uint32_t y, char c, uint32_t colour) {
int cx, cy;
// int mask[8]={1,2,4,8,16,32,64,128};
for (cy = 0; cy < 16; cy++) {
for (cx = 0; cx < 8; cx++) {
if (font[(uint8_t)c * 16 + cy] >> cx & 0x1) {
gui_putpixel(buffer, dest_width, dest_height, x + 8 - (cx + 1), y + cy, colour);
}
}
}
}
void draw_text(uint8_t *buffer, uint32_t dest_width, uint32_t dest_height, int sx, int sy, uint32_t colour, char *text) {
int i;
for (i = 0; i < strlen(text); i++) {
gui_draw_char(buffer, dest_width, dest_height, sx + (i * 8), sy, text[i], colour);
}
}
void listbox_callback(char *item, int index) {
// render preview
char temp[256];
sprintf(temp, "disk0:/system/fonts/%s.f16", item);
FILE *fptr = fopen(temp, "rb");
if (fptr) {
memset(font, 0, 4096);
if (!fread(font, 4096, 1, fptr)) {
fclose(fptr);
return;
}
fclose(fptr);
strcpy(fontname, temp);
quinn_fill_rect(window_handle, surf, 290, 180, 0, 0, 290, 180, 0xffffffff);
draw_text(surf, 290, 240, 3, 3, 0xFF000000, "The quick brown fox");
}
return;
}
void setfont_callback(void *data) {
int ret;
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (60), "b" (font));
FILE *fptr = fopen("disk0:/system/fonts/chosen.fnt", "w");
if (fptr) {
fprintf(fptr, "%s\n", fontname);
fclose(fptr);
}
}
void quit_callback(void *data) {
quinn_exit();
exit(0);
}
int fill_dir_list(struct widget_t *lb) {
int fno = open("disk0:/system/fonts/", 0, 0);
int len;
int bpos;
char temp[256];
char buffer[1024];
char buffer2[1024];
struct stat s;
if (fno >= 0) {
while (1) {
__asm__ volatile ("int $0x30" : "=a" (len) : "0" (13), "b" (fno), "c" (buffer), "d" (1024));
if (len <= 0) {
break;
}
for (bpos = 0; bpos < len;) {
struct quinn_dirent_t *dent = (struct quinn_dirent_t *)(buffer + bpos);
sprintf(buffer2, "disk0:/system/fonts/%s", dent->name);
if (!stat(buffer2, &s)) {
if (!S_ISDIR(s.st_mode)) {
if (dent->name_len > 4 && strcmp(&dent->name[dent->name_len - 4], ".f16") == 0) {
memset(temp, '\0', 256);
strncpy(temp, dent->name, dent->name_len - 4);
quinn_listbox_additem(lb, temp);
}
}
}
bpos = dent->next_offset;
}
}
close(fno);
return 1;
}
return 0;
}
int main(int argc, char **argv) {
struct widget_t *surfw;
quinn_init();
struct window_req_t *req = (struct window_req_t *)malloc(sizeof(struct window_req_t));
unsigned char *icon;
convert_xpm(sysfont_xpm, &icon);
req->x = 100;
req->y = 100;
req->width = 600;
req->height = 243;
req->icon = icon;
req->flags = 0;
strcpy(req->name, "Font Settings");
window_handle = quinn_req_window(req, exit_callback);
free(req);
free(icon);
// add list box with font listing
listbox = quinn_add_listbox(window_handle, 3, 3, 290, 240, listbox_callback);
fill_dir_list(listbox);
// add preview surface
surfw = quinn_add_surface(window_handle, 293, 3, 290, 180, NULL, NULL, NULL, NULL);
surf = quinn_surface_get_surface(surfw);
quinn_add_button(window_handle, 351, 215, 120, 25, "Set Font", NULL, setfont_callback);
quinn_add_button(window_handle, 476, 215, 120, 25, "Quit", NULL, quit_callback);
while (1) {
quinn_process(1);
}
quinn_exit();
}