summaryrefslogtreecommitdiff
path: root/opplysning.c
diff options
context:
space:
mode:
authorMartin Stensgård <mastensg@mastensg.net>2025-07-22 11:41:10 +0200
committerMartin Stensgård <mastensg@mastensg.net>2025-07-22 11:41:48 +0200
commit5fead1096ee4ffdfed9957b575e2b09e6d9637cf (patch)
tree2d07fe2ff64235bd505157d8ad947ad7532d47e1 /opplysning.c
parente6d85d4516b7d79304c8bb331a05f9ea15070967 (diff)
install, bin/opplysning-*
Diffstat (limited to 'opplysning.c')
-rw-r--r--opplysning.c306
1 files changed, 0 insertions, 306 deletions
diff --git a/opplysning.c b/opplysning.c
deleted file mode 100644
index ba4d9c9..0000000
--- a/opplysning.c
+++ /dev/null
@@ -1,306 +0,0 @@
-#define _POSIX_C_SOURCE 199309L
-
-#include <err.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <libical/ical.h>
-#include <raylib.h>
-
-#include "sqlite/sqlite3.h"
-
-enum {
- SCREEN_W = 1920,
- SCREEN_H = 1080,
-};
-
-const char *maaned[] = {
- "", "JANUAR", "FEBRUAR", "MARS", "APRIL", "MAI", "JUNI",
- "JULI", "AUGUST", "SEPTEMBER", "OKTOBER", "NOVEMBER", "DESEMBER",
-};
-const char *ukedag[] = {
- "SØNDAG", "MANDAG", "TIRSDAG", "ONSDAG", "TORSDAG", "FREDAG", "LØRDAG",
-};
-
-enum {
- MAX_EVENTS = 64,
- SIZEOF_TITLE = 60,
-};
-
-struct event {
- time_t start;
- time_t end;
- int year;
- int month;
- int day;
- int wday;
- int hour;
- int minute;
- int end_hour;
- int end_minute;
- char title[SIZEOF_TITLE];
-};
-
-struct calendar {
- char *database;
- char *title;
- char *subtitle;
- size_t num_events;
- struct event events[MAX_EVENTS];
-};
-
-void
-load_events(struct calendar *cal)
-{
- sqlite3 *db;
- if (sqlite3_open(cal->database, &db))
- errx(1, "sqlite3_open: %s", sqlite3_errmsg(db));
-
- const char *sql = "SELECT "
- "unixepoch(start), "
- "unixepoch(end), "
- "CAST(strftime('%Y', start, 'localtime') as INT), "
- "CAST(strftime('%m', start, 'localtime') as INT), "
- "CAST(strftime('%d', start, 'localtime') as INT), "
- "CAST(strftime('%w', start, 'localtime') as INT), "
- "CAST(strftime('%H', start, 'localtime') as INT), "
- "CAST(strftime('%M', start, 'localtime') as INT), "
- "CAST(strftime('%H', end , 'localtime') as INT), "
- "CAST(strftime('%M', end , 'localtime') as INT), "
- "summary "
- "FROM event "
- "WHERE datetime('now', 'start of day') < start "
- "AND summary IS NOT NULL "
- "ORDER BY start";
- sqlite3_stmt *stmt = NULL;
- if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))
- errx(1, "sqlite3_prepare_v2: %s", sqlite3_errmsg(db));
-
- size_t n = 0;
- for (;;) {
- int step = sqlite3_step(stmt);
- if (SQLITE_DONE == step)
- break;
- if (SQLITE_ROW != step)
- errx(1, "sqlite3_step: %s", sqlite3_errmsg(db));
-
- if (MAX_EVENTS <= n) {
- warnx("MAX_EVENTS exceeded at %zu", n);
- break;
- }
-
- int start = sqlite3_column_int(stmt, 0);
- int end = sqlite3_column_int(stmt, 1);
- int year = sqlite3_column_int(stmt, 2);
- int month = sqlite3_column_int(stmt, 3);
- int day = sqlite3_column_int(stmt, 4);
- int wday = sqlite3_column_int(stmt, 5);
- int hour = sqlite3_column_int(stmt, 6);
- int minute = sqlite3_column_int(stmt, 7);
- int end_hour = sqlite3_column_int(stmt, 8);
- int end_minute = sqlite3_column_int(stmt, 9);
- const char *summary =
- (const void *)sqlite3_column_text(stmt, 10);
- assert(summary);
-
- cal->events[n].start = start;
- cal->events[n].end = end;
- cal->events[n].year = year;
- cal->events[n].month = month;
- cal->events[n].day = day;
- cal->events[n].hour = hour;
- cal->events[n].minute = minute;
- cal->events[n].end_hour = end_hour;
- cal->events[n].end_minute = end_minute;
- strncpy(cal->events[n].title, summary, SIZEOF_TITLE);
- cal->events[n].wday = wday;
- ++n;
- }
-
- if (sqlite3_finalize(stmt))
- errx(1, "sqlite3_finalize: %s", sqlite3_errmsg(db));
-
- if (sqlite3_close(db))
- errx(1, "sqlite3_close: %s", sqlite3_errmsg(db));
-
- cal->num_events = n;
-}
-
-struct ray {
- Shader shader;
- RenderTexture2D target;
- int shader_u_time;
-
- Color bg;
- Color fg;
- Color hd;
- Color rd;
-
- Font font_h;
- Font font_p;
-};
-struct ray R;
-
-const char *the_non_ascii = "ÄÅÉËÞÜÚÍÓÖÁÐFGHÏŒØÆŒ©®BÑΜ"
- "äåéëþüúíóöáðfghïœøæœ©®bñµß"
- "«»";
-
-void
-ray_init(void)
-{
- SetTraceLogLevel(LOG_WARNING);
- InitWindow(SCREEN_W, SCREEN_H, "opplysning");
- SetTargetFPS(60);
-
- char *codes = calloc(128 + strlen(the_non_ascii), 1);
- if (!codes)
- err(1, "calloc");
- for (int i = 1; i < 128; ++i)
- codes[i] = i;
- memcpy(codes + 128, the_non_ascii, strlen(the_non_ascii));
- int ncp = 0;
- int *cp = LoadCodepoints(codes + 1, &ncp);
- R.font_h = LoadFontEx("font/adventpro-bold.ttf", 48, cp, ncp);
- R.font_p =
- LoadFontEx("font/BellCentennialStd-Address.ttf", 28, cp, ncp);
- UnloadCodepoints(cp);
- free(codes);
-
- R.bg = RAYWHITE;
- R.fg = BLACK;
- R.hd = (Color){0xf0, 0x4a, 0x00, 0xff};
- R.rd = (Color){0xd7, 0x21, 0x17, 0xff};
-
- R.shader = LoadShader(0, "s.glsl");
- R.shader_u_time = GetShaderLocation(R.shader, "u_time");
- R.target = LoadRenderTexture(SCREEN_W, SCREEN_H);
-}
-
-void
-blur(int x, int y, Font f, Color c, char *s)
-{
- Vector2 m = MeasureTextEx(f, s, f.baseSize, 0);
-
- BeginTextureMode(R.target);
- ClearBackground((Color){0});
- DrawTextEx(f, s, (Vector2){0, 0}, (float)f.baseSize, 0, c);
- EndTextureMode();
-
- BeginShaderMode(R.shader);
- float t = GetTime();
- SetShaderValue(R.shader, R.shader_u_time, &t, SHADER_UNIFORM_FLOAT);
- DrawTextureRec(R.target.texture,
- (Rectangle){0, SCREEN_H - m.y, m.x, -m.y},
- (Vector2){x, y}, WHITE);
- EndShaderMode();
-}
-void
-line(int x, int y, Font f, Color c, const char *s)
-{
- DrawTextEx(f, s, (Vector2){x, y}, (float)f.baseSize, 0, c);
-}
-
-void
-draw_time(int x, int y, struct timespec now)
-{
- struct tm *ti = localtime(&now.tv_sec);
- char ts[64] = {0};
- snprintf(ts, sizeof(ts), "%02d:%02d", ti->tm_hour, ti->tm_min);
- Vector2 v2_ts = MeasureTextEx(R.font_h, ts, R.font_h.baseSize, 0);
- line(x - v2_ts.x / 2, y, R.font_h, R.fg, ts);
-}
-
-void
-draw_event(int x, int y, struct timespec now, const struct event *e)
-{
- char s[128] = {0};
- snprintf(s, sizeof(s), "%02u:%02u - %02u:%02u %s", e->hour, e->minute,
- e->end_hour, e->end_minute, e->title);
- Color c = R.fg;
- if (e->start <= now.tv_sec && now.tv_sec < e->end)
- c = R.rd;
- line(x, y, R.font_p, c, s);
-}
-
-void
-draw_date(int x, int y, struct timespec now, int wday, int day, int month,
- int year)
-{
- struct tm *ti = localtime(&now.tv_sec);
- Color c = R.fg;
- if ((year == 1900 + ti->tm_year) && (month == 1 + ti->tm_mon) &&
- (day == ti->tm_mday))
- c = R.rd;
- char s[64] = {0};
- snprintf(s, sizeof(s), "%s %u. %s", ukedag[wday], day, maaned[month]);
- line(x, y, R.font_h, c, s);
-}
-
-void
-draw_calendar(int x, int y, struct timespec now, struct calendar *cal)
-
-{
- x += 20;
- line(x, y, R.font_h, R.fg, cal->title);
- y += 50;
- line(x, y, R.font_p, R.fg, cal->subtitle);
-
- int year = 0, month = 0, day = 0;
- for (size_t i = 0; i < cal->num_events; ++i) {
- const struct event *e = &cal->events[i];
- if (year != e->year || month != e->month || day != e->day) {
- if (SCREEN_H - 2 * R.font_h.baseSize < y)
- break;
- year = e->year;
- month = e->month;
- day = e->day;
- y += 40;
- draw_date(x, y, now, e->wday, e->day, e->month,
- e->year);
- y += 20;
- }
- y += 40;
- draw_event(x, y, now, e);
- }
-}
-
-int
-main(void)
-{
- struct calendar google = {
- .database = "var/google.db",
- .title = "Reservasjoner",
- .subtitle = "Hentet fra Google-kalenderen «Bitraf booking»",
- };
- struct calendar meetup = {
- .database = "var/meetup.db",
- .title = "Begivenheter",
- .subtitle = "Hentet fra https://www.meetup.com/bitraf/",
- };
-
- ray_init();
- while (!WindowShouldClose()) {
- if (IsKeyPressed(KEY_R)) {
- double t0 = GetTime();
- load_events(&google);
- load_events(&meetup);
- double t1 = GetTime();
- fprintf(stderr, "%6.3f ms\n", (t1 - t0) * 1000.0);
- }
-
- struct timespec now = {0};
- clock_gettime(CLOCK_REALTIME, &now);
-
- BeginDrawing();
- ClearBackground(R.bg);
- draw_time(SCREEN_W / 2 - 100, 0, now);
- draw_calendar(0, 0, now, &meetup);
- draw_calendar(SCREEN_W / 2, 0, now, &google);
- EndDrawing();
- }
- CloseWindow();
-}