This commit is contained in:
mtgmonkey
2025-12-09 22:18:41 +01:00
commit 5e2d2b89c8
5 changed files with 14342 additions and 0 deletions

26
flake.lock generated Normal file
View File

@@ -0,0 +1,26 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1764947035,
"narHash": "sha256-EYHSjVM4Ox4lvCXUMiKKs2vETUSL5mx+J2FfutM7T9w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a672be65651c80d3f592a89b3945466584a22069",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixpkgs-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

91
flake.nix Normal file
View File

@@ -0,0 +1,91 @@
{
inputs = {
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
};
outputs = {nixpkgs, ...}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
debugGhcOptions = pkgs.lib.concatStringsSep " " (debugGhcFlags ++ commonGhcFlags);
debugGhcFlags =
[
"-O0"
"-Wall"
"-Widentities"
"-Wincomplete-record-updates"
"-Wincomplete-uni-patterns"
# "-Wmissing-export-lists"
"-Wmissing-home-modules"
"-Wpartial-fields"
"-Wredundant-constraints"
]
++ commonGhcFlags;
haddockOptions = pkgs.lib.concatStringsSep " " haddockFlags;
haddockFlags = [
"--html"
"--odir docs"
"--optghc=-i./src"
"src/Game.hs"
];
releaseGhcOptions = pkgs.lib.concatStringsSep " " (releaseGhcFlags ++ commonGhcFlags);
releaseGhcFlags =
[
"-O2"
"-threaded"
"-rtsopts"
"-with-rtsopts=-N"
"-main-is Main"
]
++ commonGhcFlags;
noHaddockOptions = "";
commonGhcFlags = [
"-i./src"
"-threaded"
"-rtsopts"
"-with-rtsopts=-N"
"-main-is Main"
];
ghcPackages = p: [
];
buildDeps = [
pkgs.pkg-config
pkgs.wayland-protocols
pkgs.wayland-scanner
pkgs.egl-wayland
pkgs.libGL
pkgs.libxkbcommon
pkgs.wayland
pkgs.xorg.libX11
pkgs.xorg.libXcursor
pkgs.xorg.libXi
pkgs.xorg.libXrandr
];
in {
packages.${system} = {
debug = pkgs.callPackage ./package.nix {
ghcOptions = debugGhcOptions;
haddockOptions = noHaddockOptions;
inherit ghcPackages;
inherit buildDeps;
};
release = pkgs.callPackage ./package.nix {
ghcOptions = releaseGhcOptions;
haddockOptions = noHaddockOptions;
inherit ghcPackages;
inherit buildDeps;
};
docs = pkgs.callPackage ./package.nix {
ghcOptions = "--version";
inherit haddockOptions;
inherit ghcPackages;
inherit buildDeps;
};
default = pkgs.callPackage ./package.nix {
ghcOptions = releaseGhcOptions;
inherit haddockOptions;
inherit ghcPackages;
inherit buildDeps;
};
};
};
}

14040
lib/RGFW.h Normal file

File diff suppressed because it is too large Load Diff

64
package.nix Normal file
View File

@@ -0,0 +1,64 @@
{
buildDeps,
haskellPackages,
lib,
pkgs,
stdenv,
ghcOptions,
haddockOptions,
ghcPackages,
...
}:
stdenv.mkDerivation {
pname = "hs-rgfw";
version = "0.1.0";
src = ./.;
nativeBuildInputs =
[
(haskellPackages.ghcWithPackages ghcPackages)
]
++ buildDeps;
buildInputs =
[
]
++ buildDeps;
configurePhase = ''
export PKG_CONFIG_PATH=/run/current-system/sw/lib/pkgconfig
mkdir ccode
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml ./ccode/xdg-shell.c
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml ./ccode/xdg-toplevel-icon-v1.c
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml ./ccode/xdg-decoration-unstable-v1.c
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/relative-pointer/relative-pointer-unstable-v1.xml ./ccode/relative-pointer-unstable-v1.c
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml ./ccode/pointer-constraints-unstable-v1.c
wayland-scanner public-code ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/xdg-output/xdg-output-unstable-v1.xml ./ccode/xdg-output-unstable-v1.c
mkdir headers
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml ./headers/xdg-shell.h
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml ./headers/xdg-toplevel-icon-v1.h
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml ./headers/xdg-decoration-unstable-v1.h
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/relative-pointer/relative-pointer-unstable-v1.xml ./headers/relative-pointer-unstable-v1.h
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml ./headers/pointer-constraints-unstable-v1.h
wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/unstable/xdg-output/xdg-output-unstable-v1.xml ./headers/xdg-output-unstable-v1.h
'';
buildPhase = ''
mkdir src/lib
cp lib/* src/lib/
cp ccode/*.c ./
ghc ${ghcOptions} ./src/Main.hs -o ./Main $(pkg-config --cflags --libs gl wayland-client wayland-egl wayland-cursor xkbcommon x11 xcursor xrandr xi) -I./headers/ $(ls *.c)
mkdir ./docs
haddock ${haddockOptions}
'';
installPhase = ''
mkdir -p $out/bin
cp ./Main $out/bin/hs-rgfw
cp ./docs $out/docs -r
'';
meta = {
homepage = "https://mtgmonkey.net";
license = lib.licenses.bsd3;
mainProgram = "hs-rgfw";
platforms = ["x86_64-linux"];
};
}

121
src/Main.hs Normal file
View File

@@ -0,0 +1,121 @@
{-# LANGUAGE CApiFFI #-}
module Main (main) where
import Data.Bits (shiftL, (.|.))
import Foreign
import Foreign.C.String
import Foreign.C.Types
--------------------------------------------------------------------------------
-- main
--------------------------------------------------------------------------------
main :: IO ()
main = do
window <- withCString "a window" (\name ->
rgfwCreateWindow
name
0
0
800
600
$ mkWindowFlags
[ WindowCenter
, WindowNoResize
, WindowOpenGL
]
)
let loop = do
putStrLn $ show window
putStrLn
$ show
$ mkWindowFlags
[ WindowCenter
, WindowNoResize
, WindowOpenGL
]
shouldClose <- rgfwWindowShouldClose window
if 0 == shouldClose
then return ()
else loop
loop
--------------------------------------------------------------------------------
-- Haskell-ier abstractions
--------------------------------------------------------------------------------
data WindowFlags
= WindowNoBorder
| WindowNoResize
| WindowAllowDND
| WindowHideMouse
| WindowFullscreen
| WindowTransparent
| WindowCenter
| WindowRawMouse
| WindowScaleToMonitor
| WindowHide
| WindowMaximize
| WindowCenterCursor
| WindowFloating
| WindowFocusOnShow
| WindowMinimize
| WindowFocus
| WindowOpenGL
| WindowEGL
| WindowedFullscreen
mkWindowFlags :: [WindowFlags] -> RGFWwindowFlags
mkWindowFlags [] = 0
mkWindowFlags (flag:flags) =
let
shift =
case flag of
WindowNoBorder -> 0
WindowNoResize -> 1
WindowAllowDND -> 2
WindowHideMouse -> 3
WindowFullscreen -> 4
WindowTransparent -> 5
WindowCenter -> 6
WindowRawMouse -> 7
WindowScaleToMonitor -> 8
WindowHide -> 9
WindowMaximize -> 10
WindowCenterCursor -> 11
WindowFloating -> 12
WindowFocusOnShow -> 13
WindowMinimize -> 14
WindowFocus -> 15
WindowOpenGL -> 17
WindowEGL -> 18
_ -> 19 -- TODO fix this silent error, implement windowedFullscreen
in
(shiftL 1 shift) .|. (mkWindowFlags flags)
--------------------------------------------------------------------------------
-- directly from RFGW.h
--------------------------------------------------------------------------------
-- RGFWindow
data RGFWwindow
-- ptr
type RGFWwindowPtr = Ptr RGFWwindow
-- flags to create
type RGFWwindowFlags = Word32
type RGFWbool = CUInt
foreign import capi "lib/RGFW.h RGFW_createWindow" rgfwCreateWindow
:: CString
-> Int32
-> Int32
-> Int32
-> Int32
-> RGFWwindowFlags
-> IO RGFWwindowPtr
foreign import capi "lib/RGFW.h RGFW_window_shouldClose" rgfwWindowShouldClose
:: RGFWwindowPtr
-> IO RGFWbool