{"id":13836391,"url":"https://github.com/zserge/fenster","last_synced_at":"2025-04-05T00:09:40.038Z","repository":{"id":65226335,"uuid":"588617710","full_name":"zserge/fenster","owner":"zserge","description":"The most minimal cross-platform GUI library","archived":false,"fork":false,"pushed_at":"2023-12-20T15:14:13.000Z","size":540,"stargazers_count":495,"open_issues_count":14,"forks_count":30,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-02-17T07:34:09.758Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zserge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-13T15:06:25.000Z","updated_at":"2024-05-30T01:26:47.917Z","dependencies_parsed_at":"2024-05-30T01:26:45.699Z","dependency_job_id":"813e16ca-950b-4569-a751-a0165a2edd26","html_url":"https://github.com/zserge/fenster","commit_stats":{"total_commits":45,"total_committers":4,"mean_commits":11.25,"dds":0.2666666666666667,"last_synced_commit":"63e84e0a7f0229bd9758b425a1cafd73644f3063"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zserge%2Ffenster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zserge%2Ffenster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zserge%2Ffenster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zserge%2Ffenster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zserge","download_url":"https://codeload.github.com/zserge/fenster/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266564,"owners_count":20910836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T15:00:44.023Z","updated_at":"2025-04-05T00:09:40.008Z","avatar_url":"https://github.com/zserge.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# Fenster\n\nFenster /ˈfɛnstɐ/ -- a German word for \"window\".\n\nThis library provides the most minimal and highly opinionated way to display a cross-platform 2D canvas. If you remember Borland BGI or drawing things in QBASIC or `INT 10h`- you know what I mean. As a nice bonus you also get cross-platform keyboard/mouse input and audio playback in only a few lines of code.\n\n## What it does for you\n\n* Single application window of given size with a title.\n* Application lifecycle and system events are all handled automatically.\n* Minimal 24-bit RGB framebuffer.\n* Cross-platform keyboard events (keycodes).\n* Cross-platform mouse events (X/Y + mouse click).\n* Cross-platform timers to have a stable FPS rate.\n* Cross-platform audio playback (WinMM, CoreAudio, ALSA).\n* Simple polling API without a need for callbacks or multithreading (like Arduino/Processing).\n* One C99 header of ~300LOC, easy to understand and extend.\n* Go bindings (`import \"github.com/zserge/fenster\"`, see [godoc](https://pkg.go.dev/github.com/zserge/fenster))\n* Zig bindings (see [examples/minimal-zig](/examples/minimal-zig))\n* Lua bindings (see https://github.com/jonasgeiler/lua-fenster)\n* And, yes, [it can run Doom](/examples/doom-c)!\n\n## Example\n\nHere's how to draw white noise:\n\n```c\n// main.c\n#include \"fenster.h\"\n#define W 320\n#define H 240\nint main() {\n  uint32_t buf[W * H];\n  struct fenster f = { .title = \"hello\", .width = W, .height = H, .buf = buf };\n  fenster_open(\u0026f);\n  while (fenster_loop(\u0026f) == 0) {\n    for (int i = 0; i \u003c W; i++) {\n      for (int j = 0; j \u003c H; j++) {\n        fenster_pixel(\u0026f, i, j) = rand();\n      }\n    }\n  }\n  fenster_close(\u0026f);\n  return 0;\n}\n```\n\nCompile it and run:\n\n```\n# Linux\ncc main.c -lX11 -lasound -o main \u0026\u0026 ./main\n# macOS\ncc main.c -framework Cocoa -framework AudioToolbox -o main \u0026\u0026 ./main\n# windows\ncc main.c -lgdi32 -lwinmm -o main.exe \u0026\u0026 main.exe\n```\n\nThat's it.\n\n## API\n\nAPI is designed to be a polling loop, where on every iteration the framebuffer get updated and the user input (mouse/keyboard) can be polled.\n\n```c\nstruct fenster {\n  const char *title; /* window title */\n  const int width; /* window width */\n  const int height; /* window height */\n  uint32_t *buf; /* window pixels, 24-bit RGB, row by row, pixel by pixel */\n  int keys[256]; /* keys are mostly ASCII, but arrows are 17..20 */\n  int mod;       /* mod is 4 bits mask, ctrl=1, shift=2, alt=4, meta=8 */\n  int x;         /* mouse X coordinate */\n  int y;         /* mouse Y coordinate */\n  int mouse;     /* 0 = no buttons pressed, 1 = left button pressed */\n};\n```\n\n* `int fenster_open(struct fenster *f)` - opens a new app window.\n* `int fenster_loop(struct fenster *f)` - handles system events and refreshes the canvas. Returns negative values when app window is closed.\n* `void fenster_close(struct fenster *f)` - closes the window and exists the graphical app.\n* `void fenster_sleep(int ms)` - pauses for `ms` milliseconds.\n* `int64_t fenster_time()` - returns current time in milliseconds.\n* `fenster_pixel(f, x, y) = 0xRRGGBB` - set pixel color.\n* `uint32_t px = fenster_pixel(f, x, y);` - get pixel color.\n\nSee [examples/drawing-c](/examples/drawing-c) for more old-school drawing primitives, but also feel free to experiment with your own graphical algorithms!\n\n## License\n\nCode is distributed under MIT license, feel free to use it in your proprietary projects as well.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzserge%2Ffenster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzserge%2Ffenster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzserge%2Ffenster/lists"}