diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dux/_freepthrdhandl.cc | 26 | ||||
-rw-r--r-- | src/dux/_getpthrdhandl.cc | 26 | ||||
-rw-r--r-- | src/dux/_pthrdcrt.cc | 30 | ||||
-rw-r--r-- | src/dux/_pthrdjoin.cc | 32 | ||||
-rw-r--r-- | src/dux/_setsiginthandl.cc | 29 | ||||
-rw-r--r-- | src/dux/_siginthandl.cc | 23 | ||||
-rw-r--r-- | src/dux/_sigtocsig.cc | 92 | ||||
-rw-r--r-- | src/dux/abrt.cc | 46 | ||||
-rw-r--r-- | src/dux/endgfx.cc | 47 | ||||
-rw-r--r-- | src/dux/exit.cc | 29 | ||||
-rw-r--r-- | src/dux/getenv.cc | 30 | ||||
-rw-r--r-- | src/dux/goatmaster.cc | 24 | ||||
-rw-r--r-- | src/dux/initgfx.cc | 64 | ||||
-rw-r--r-- | src/dux/priv.hh | 58 | ||||
-rw-r--r-- | src/dux/qexit.cc | 46 | ||||
-rw-r--r-- | src/dux/raise.cc | 53 | ||||
-rw-r--r-- | src/dux/sighandl.cc | 94 | ||||
-rw-r--r-- | src/dux/sleep.cc | 49 | ||||
-rw-r--r-- | src/dux/trap.cc | 31 | ||||
-rw-r--r-- | src/dux/unreach.cc | 30 | ||||
-rw-r--r-- | src/dux/win.cc | 144 |
21 files changed, 1003 insertions, 0 deletions
diff --git a/src/dux/_freepthrdhandl.cc b/src/dux/_freepthrdhandl.cc new file mode 100644 index 0000000..9f499b5 --- /dev/null +++ b/src/dux/_freepthrdhandl.cc @@ -0,0 +1,26 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/thrd> + +#include "priv.hh" + +auto ::dux::_freepthrdhandl(void * const dux_restr _pthrdhandl) noexcept -> void { + ::delete static_cast<::dux::_pthrddat *>(_pthrdhandl); +} diff --git a/src/dux/_getpthrdhandl.cc b/src/dux/_getpthrdhandl.cc new file mode 100644 index 0000000..4968d44 --- /dev/null +++ b/src/dux/_getpthrdhandl.cc @@ -0,0 +1,26 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/thrd> + +#include "priv.hh" + +auto ::dux::_getpthrdhandl() -> void * { + return ::new ::dux::_pthrddat; +} diff --git a/src/dux/_pthrdcrt.cc b/src/dux/_pthrdcrt.cc new file mode 100644 index 0000000..cb9a652 --- /dev/null +++ b/src/dux/_pthrdcrt.cc @@ -0,0 +1,30 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/thrd> +#include <pthread.h> + +#include "priv.hh" + +auto ::dux::_pthrdcrt(void * const dux_restr _pthrdhandl,auto (* _fn)(void *) -> void *,void const * const dux_restr _arg) -> void { + [[maybe_unused]] auto const thrddat = static_cast<::dux::_pthrddat *>(_pthrdhandl); + if (::pthread_create(&thrddat->pthrd,nullptr,_fn,const_cast<void *>(_arg)) != 0x0) [[unlikely]] { + throw ::dux::thrderr("Unable to initiate thread!"); + } +} diff --git a/src/dux/_pthrdjoin.cc b/src/dux/_pthrdjoin.cc new file mode 100644 index 0000000..33266ee --- /dev/null +++ b/src/dux/_pthrdjoin.cc @@ -0,0 +1,32 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/thrd> +#include <pthread.h> + +#include "priv.hh" + +auto ::dux::_pthrdjoin(void * const dux_restr _pthrdhandl) -> void * { + [[maybe_unused]] auto const thrddat = static_cast<::dux::_pthrddat *>(_pthrdhandl); + void * ret{nullptr}; + if (::pthread_join(thrddat->pthrd,&ret) != 0x0) [[unlikely]] { + throw ::dux::thrderr("Unable to join thread!"); + } + return ret; +} diff --git a/src/dux/_setsiginthandl.cc b/src/dux/_setsiginthandl.cc new file mode 100644 index 0000000..ba6c9a4 --- /dev/null +++ b/src/dux/_setsiginthandl.cc @@ -0,0 +1,29 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> + +#include "priv.hh" + +auto ::dux::_setsiginthandl() -> void { + ::dux::dbgprint(U"dux :: Setting the SIGINT signal handler!\n"); + if (!::dux::_inst.siginthandlset) { + ::dux::_inst.prevsiginthandl = ::dux::sighandl(::dux::sig::int_,::dux::_siginthandl); + ::dux::_inst.siginthandlset = true; + return; + } + ::dux::dbgprint(U"dux :: The SIGINT signal handler is already set!\n"); +}; diff --git a/src/dux/_siginthandl.cc b/src/dux/_siginthandl.cc new file mode 100644 index 0000000..5a9bb13 --- /dev/null +++ b/src/dux/_siginthandl.cc @@ -0,0 +1,23 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> + +#include "priv.hh" + +auto ::dux::_siginthandl(::dux::sig) noexcept -> void { + ::dux::_inst.hassigint = true; /* We have detected the SIGINT signal. The ::dux::win::pollevt function will check this value. */ +}; diff --git a/src/dux/_sigtocsig.cc b/src/dux/_sigtocsig.cc new file mode 100644 index 0000000..3e2ca71 --- /dev/null +++ b/src/dux/_sigtocsig.cc @@ -0,0 +1,92 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> +#include <signal.h> + +#include "priv.hh" + +auto ::dux::_sigtocsig(::dux::sig const _sig) noexcept -> int { + switch (_sig) { + default: + ::dux::print(U"dux :: _::dux::_sigtocsig recieved unknown signal!\n"); + ::dux::abrt(); + case ::dux::sig::abrt: + return SIGABRT; + case ::dux::sig::fpe: + return SIGFPE; + case ::dux::sig::ill: + return SIGILL; + case ::dux::sig::int_: + return SIGINT; + case ::dux::sig::segv: + return SIGSEGV; + case ::dux::sig::term: + return SIGTERM; +#if defined(dux_os_posix) + case ::dux::sig::alrm: + return SIGALRM; + case ::dux::sig::bus: + return SIGBUS; + case ::dux::sig::cont: + return SIGCONT; + case ::dux::sig::hup: + return SIGHUP; + case ::dux::sig::iot: + return SIGIOT; + case ::dux::sig::kill: + return SIGKILL; + case ::dux::sig::pipe: + return SIGPIPE; + case ::dux::sig::poll: + return SIGPOLL; + case ::dux::sig::prof: + return SIGPROF; + case ::dux::sig::quit: + return SIGQUIT; + case ::dux::sig::rtmax: + return SIGRTMAX; + case ::dux::sig::rtmin: + return SIGRTMIN; + case ::dux::sig::stop: + return SIGSTOP; + case ::dux::sig::sys: + return SIGSYS; + case ::dux::sig::trap: + return SIGTRAP; + case ::dux::sig::tstp: + return SIGTSTP; + case ::dux::sig::ttin: + return SIGTTIN; + case ::dux::sig::ttou: + return SIGTTOU; + case ::dux::sig::urg: + return SIGURG; + case ::dux::sig::usr1: + return SIGUSR1; + case ::dux::sig::usr2: + return SIGUSR2; + case ::dux::sig::vtalrm: + return SIGVTALRM; + case ::dux::sig::winch: + return SIGWINCH; + case ::dux::sig::xcpu: + return SIGXCPU; + case ::dux::sig::xfsz: + return SIGXFSZ; +#endif + } +}; diff --git a/src/dux/abrt.cc b/src/dux/abrt.cc new file mode 100644 index 0000000..391089f --- /dev/null +++ b/src/dux/abrt.cc @@ -0,0 +1,46 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> +#if defined(dux_os_posix) +#include <pthread.h> +#endif + +namespace dux::_static { +#if defined(dux_os_posix) + static ::pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +#endif +} + +auto ::dux::abrt() noexcept -> void { + ::pthread_mutex_lock(&::dux::_static::lock); /* Lock this so we will not abort from multiple threads. */ + ::dux::dbgprint(U"dux :: Aborting!\n"); + ::dux::dbgprint(U"dux :: Raising SIGABRT!\n"); + ::dux::raise(::dux::sig::abrt); /* We will now raise SIGABRT in an attempt to quit. */ + ::dux::dbgprint(U"dux :: Signal handler returned! Reset it!\n"); + ::dux::sighandl(::dux::sig::abrt,::dux::dflsighandl); /* The signal handler has returned, and so we will attempt to set the default handler. */ + ::dux::dbgprint(U"dux :: Raising SIGABRT!\n"); + ::dux::raise(::dux::sig::abrt); /* Raise SIGABRT again to call the default signal handler. */ + ::dux::dbgprint(U"dux :: Default signal handler returned! Trapping!\n"); + ::dux::trap(); /* The default signal handler returned, so we will trap or never return. */ +} +auto ::dux::abrt(::dux::str const & _msg) noexcept -> void { + ::dux::print(U"dux :: Aborting due to \"$\"!\n",_msg); + ::dux::abrt(); +} diff --git a/src/dux/endgfx.cc b/src/dux/endgfx.cc new file mode 100644 index 0000000..90962ce --- /dev/null +++ b/src/dux/endgfx.cc @@ -0,0 +1,47 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> +#include <dux/media> +#if defined(dux_gfxproto_gl) +#include <GL/gl.h> +#endif +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#include <wayland-client.h> +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) +#include <xcb/xcb.h> +#if defined(dux_gfxproto_gl) +#include <GL/glx.h> +#include <X11/Xlib-xcb.h> +#endif +#endif + +#include "priv.hh" + +auto ::dux::endgfx() -> void { + ::dux::dbgprint(U"dux :: Ending the graphics module...\n"); + dux_ass(!::dux::_inst.numwin,"Ammount of windows is non-zero!"); + if (!::dux::_inst.gfxinit) [[unlikely]] { + goto isend; + } +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::dux::print(U"dux :: Disconnecting from the X server!\n"); + ::xcb_disconnect(::dux::_inst.xconn); +#endif +isend:; + ::dux::dbgprint(U"dux :: Ending successful!\n"); +} diff --git a/src/dux/exit.cc b/src/dux/exit.cc new file mode 100644 index 0000000..3d0b15a --- /dev/null +++ b/src/dux/exit.cc @@ -0,0 +1,29 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> + +#include <cstdlib> + +auto ::dux::exit(::dux::stat const _stat) noexcept -> void { + if (_stat == ::dux::stat::err) { + ::std::exit(EXIT_FAILURE); + } + ::std::exit(EXIT_SUCCESS); +} diff --git a/src/dux/getenv.cc b/src/dux/getenv.cc new file mode 100644 index 0000000..fce63e2 --- /dev/null +++ b/src/dux/getenv.cc @@ -0,0 +1,30 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <cstdlib> +#include <dux/sys> + +auto ::dux::getenv(char const * const dux_restr _env) -> char const * { + if (auto const envval = ::std::getenv(_env);envval == nullptr) [[unlikely]] { + throw ::dux::runerr("Environment variable does not exist!"); + } + else { + return envval; + } +} diff --git a/src/dux/goatmaster.cc b/src/dux/goatmaster.cc new file mode 100644 index 0000000..8eb350b --- /dev/null +++ b/src/dux/goatmaster.cc @@ -0,0 +1,24 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> + +[[dux_attr_cold]] extern "C" void goatmaster(int const _x) { /* Test function for dynamic linking. */ + ::dux::print(U"The Goat Master has been summoned with the number $!\n",_x); +} diff --git a/src/dux/initgfx.cc b/src/dux/initgfx.cc new file mode 100644 index 0000000..3ab4141 --- /dev/null +++ b/src/dux/initgfx.cc @@ -0,0 +1,64 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> +#include <dux/media> +#if defined(dux_gfxproto_gl) +#include <GL/gl.h> +#endif +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#include <wayland-client.h> +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) +#include <xcb/xcb.h> +#if defined(dux_gfxproto_gl) +#include <GL/glx.h> +#include <X11/Xlib-xcb.h> +#endif +#endif + +#include "priv.hh" + +auto ::dux::initgfx() -> void { + ::dux::dbgprint(U"dux :: Initialising the graphics module...\n"); + if (::dux::_inst.gfxinit) [[unlikely]] { + goto isinit; + } +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) + try { + auto const * const dux_restr envval = ::dux::getenv("XDG_SESSION_TYPE"); + if (!!::dux::cstrcmp(envval,"wayland")) [[unlikely]] { + ::dux::print(U"dux :: Environment variable \"XDG_SESSION_TYPE\" is not set to \"wayland\", but dux is targeting Wayland!\n"); + } + } + catch (::dux::except const & e) { + } + ::dux::dbgprint(U"dux :: Wayland support is experimental!\n"); + ::dux::_inst.wldisp = ::wl_display_connect(nullptr); + if (::dux::_inst.wldisp == nullptr) [[unlikely]] { + throw ::dux::runerr("Unable to open Wayland display!"); + } +#else + if (::dux::_inst.xconn = ::xcb_connect(nullptr,nullptr);::dux::_inst.xconn == nullptr) [[unlikely]] { + throw ::dux::runerr("Unable to open connection to X server."); + } + ::dux::dbgprint(U"dux :: Made a connection to an X server!\n"); + ::dux::_inst.xscrn = ::xcb_setup_roots_iterator(xcb_get_setup(::dux::_inst.xconn)).data; + ::dux::dbgprint(U"dux :: Set up roots iterator!\n"); +#endif + ::dux::_inst.gfxinit = true; +isinit:; + ::dux::dbgprint(U"dux :: Initialisation successful!\n"); +} diff --git a/src/dux/priv.hh b/src/dux/priv.hh new file mode 100644 index 0000000..1c497d5 --- /dev/null +++ b/src/dux/priv.hh @@ -0,0 +1,58 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#if !defined(dux_hdr_priv) +#define dux_hdr_priv + +#include <dux/sys> +#if defined(dux_os_posix) +#include <pthread.h> +#endif +#if defined(dux_winsproto_wl) +#include <wayland-client.h> +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) +#include <xcb/xcb.h> +#endif + +namespace dux { + class _insttyp { + public: + bool gfxinit {false}; + bool hassigint {false}; + ::dux::uint16 numwin {::dux::uint16v(0x0)}; + void (* prevsiginthandl)(::dux::sig){::dux::dflsighandl}; /* Used for setting the previous signal handler in case there aren't any open windows to handle the signal. */ + bool siginthandlset {false}; +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) + ::wl_display * wldisp{nullptr}; +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::xcb_connection_t * xconn{nullptr}; + ::xcb_screen_t * xscrn{nullptr}; +#endif + } inline _inst; + +#if defined(dux_os_posix) + class _pthrddat { + public: + pthread_t pthrd; + }; +#endif + + auto _setsiginthandl() -> void; + auto _siginthandl( ::dux::sig) noexcept -> void; + auto _sigtocsig( ::dux::sig sig) noexcept -> int; +} + +#endif diff --git a/src/dux/qexit.cc b/src/dux/qexit.cc new file mode 100644 index 0000000..8cebfb8 --- /dev/null +++ b/src/dux/qexit.cc @@ -0,0 +1,46 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> + +#if defined(dux_os_linux) +#include <sys/syscall.h> +#include <unistd.h> +#elif defined(dux_os_posix) +#include <stdlib.h> +#else +#include <cstdlib> +#endif + +auto ::dux::qexit(::dux::stat const _stat) noexcept -> void { +#if defined(dux_os_linux) + auto const stat = _stat == ::dux::stat::ok ? 0x0 : 0x1; + ::syscall(__NR_exit_group,stat); + ::syscall(__NR_exit,stat); + ::dux::trap(); +#else + auto const stat = _stat == ::dux::stat::ok ? EXIT_SUCCESS : EXIT_FAILURE; +#if defined(dux_os_posix) + ::_exit(stat); + ::dux::trap(); +#else + ::std::_Exit(stat); +#endif +#endif +} diff --git a/src/dux/raise.cc b/src/dux/raise.cc new file mode 100644 index 0000000..3c0d020 --- /dev/null +++ b/src/dux/raise.cc @@ -0,0 +1,53 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> + +#include <signal.h> +#if defined(dux_os_linux) +#include <sys/syscall.h> +#include <unistd.h> +#else +#include <pthread.h> +#endif + +#include "priv.hh" + +auto ::dux::raise(::dux::sig const _sig) noexcept -> void { + ::dux::dbgprint(U"dux :: Raising signal #$!\n",static_cast<int>(_sig)); +#if !defined(dux_os_posix) + if (_sig == ::dux::sig::kill) { + ::dux::abrt(); + } + if (_sig == ::dux::sig::trap) { + ::dux::trap(); + } +#endif + auto const sig = ::dux::_sigtocsig(_sig); +#if defined(dux_os_linux) + ::dux::dbgprint(U"dux :: Killing process via syscall!\n"); + ::syscall(__NR_kill,::syscall(__NR_getpid),sig); +#elif defined(dux_os_posix) +::dux::dbgprint(U"dux :: Killing thread!\n"); + ::pthread_kill(::pthread_self(),sig); +#else + ::dux::dbgprint(U"dux :: Raising signal!\n"); + ::raise(sig); +#endif +} diff --git a/src/dux/sighandl.cc b/src/dux/sighandl.cc new file mode 100644 index 0000000..8e21505 --- /dev/null +++ b/src/dux/sighandl.cc @@ -0,0 +1,94 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/io> + +#include <cerrno> +#include <signal.h> +#if defined(dux_os_linux) +#include <sys/syscall.h> +#include <unistd.h> +#endif + +#include "priv.hh" + +namespace dux::_static { + static auto (* _sighandls[::dux::numsig])(::dux::sig) -> void; + + static auto _sigwrap(int sig) -> void; +} + +static auto ::dux::_static::_sigwrap(int const _sig) -> void { +#if !defined(dux_os_posix) + ::signal(_sig,::dux::_static::sigwrap); +#endif + auto const sig = [&]() { + switch(_sig) { + default: + ::dux::abrt(); + case SIGABRT: + return ::dux::sig::abrt; + case SIGFPE: + return ::dux::sig::fpe; + case SIGILL: + return ::dux::sig::ill; + case SIGINT: + return ::dux::sig::int_; + case SIGSEGV: + return ::dux::sig::segv; + case SIGTERM: + return ::dux::sig::term; + } + }(); + ::dux::_static::_sighandls[static_cast<::dux::usz>(sig)](sig); +} + +auto ::dux::sighandl(::dux::sig const _sig,auto (* const _handl)(::dux::sig) -> void) -> auto (&)(::dux::sig) -> void { + ::dux::print(U"dux :: Setting signal handler!\n"); + auto & handl = ::dux::_static::_sighandls[static_cast<::dux::usz>(_sig)]; + auto const oldhandl = handl; + handl = _handl; + auto const sig = ::dux::_sigtocsig(_sig); + if (_handl == ::dux::dflsighandl) { + ::signal(sig,SIG_DFL); + goto ret; + } + { +#if defined(dux_os_posix) + struct ::sigaction sigact{}; + sigact.sa_handler = ::dux::_static::_sigwrap; + ::sigemptyset(&sigact.sa_mask); + sigact.sa_flags = SA_RESTART; +#endif + if ([&]() { +//#if defined(dux_os_linux) +// return ::syscall(__NR_rt_sigaction,sig,&sigact,nullptr,sizeof(::sigset_t)) == -0x1l; /* This syscall returns EINVAL and I could not get it to work. */ +//#elif defined(dux_os_posix) +#if defined(dux_os_posix) + return ::sigaction(sig,&sigact,nullptr) == -0x1; +#else + return ::std::signal(sig,::dux::_static::_sigwrap) == SIG_ERR; +#endif + }()) [[unlikely]] { + throw ::dux::runerr("Unable to set signal handler!"); + } + } +ret:; + return *oldhandl; +} diff --git a/src/dux/sleep.cc b/src/dux/sleep.cc new file mode 100644 index 0000000..84a74da --- /dev/null +++ b/src/dux/sleep.cc @@ -0,0 +1,49 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> +#if defined(dux_os_posix) +#include <unistd.h> +#if defined(dux_os_linux) +#include <sys/syscall.h> +#else +#include <time.h> +#endif +#endif + +auto ::dux::sleep(::dux::uint64 const _sec,::dux::uint64 const _nsecx,::dux::uint64 const _nsecy) noexcept -> void { +#if defined(dux_os_posix) +#if defined(dux_os_linux) + class { + public: + ::dux::uint64 tv_sec; + long tv_nsec; + } timespec; +#else + ::timespec timespec; +#endif + timespec.tv_sec = _sec; + timespec.tv_nsec = static_cast<long>(static_cast<float>(_nsecx) / static_cast<float>(_nsecy) * 0x3B9ACA00p0); +#if defined(dux_os_linux) + ::syscall(__NR_nanosleep,×pec,×pec); +#else + ::nanosleep(×pec,×pec); +#endif +#endif +} diff --git a/src/dux/trap.cc b/src/dux/trap.cc new file mode 100644 index 0000000..a689451 --- /dev/null +++ b/src/dux/trap.cc @@ -0,0 +1,31 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> + +auto ::dux::trap() noexcept -> void { + for (;;) { +#if defined(dux_os_unix) + ::dux::raise(::dux::sig::trap); +#elif dux_hasbuiltin(__builtin_trap) + ::__builtin_trap(); +#elif dux_hasbuiltin(__debugbreak) + ::__debugbreak(); +#else + ::dux::qexit(::dux::stat::err); +#endif + } +}; diff --git a/src/dux/unreach.cc b/src/dux/unreach.cc new file mode 100644 index 0000000..f03de41 --- /dev/null +++ b/src/dux/unreach.cc @@ -0,0 +1,30 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your + option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + License for more details. + + You should have received a copy of the GNU Affero General Public License + along with dux. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <dux/sys> + +auto ::dux::unreach() noexcept -> void { +#if dux_hasbuiltin(__assume) + ::__assume(false); +#elif dux_hasbuiltin(__builtin_unreachable) + ::__builtin_unreachable(); +#else + ::dux::trap(); +#endif +} diff --git a/src/dux/win.cc b/src/dux/win.cc new file mode 100644 index 0000000..2957892 --- /dev/null +++ b/src/dux/win.cc @@ -0,0 +1,144 @@ +/* + Copyright 2021 Gabriel Jensen + + This file is part of dux. + + dux is free software: + you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with dux. + If not, see <https://www.gnu.org/licenses/>. +*/ + +#include <cstdlib> +#include <dux/io> +#include <dux/media> +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#include <wayland-client.h> +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) +#include <xcb/xcb.h> +#include <xcb/xcb_atom.h> +#endif + +#include "priv.hh" + +namespace dux { + class windat { + public: + bool open{false}; +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) + ::wl_shell_surface * wlsurf{nullptr}; +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::xcb_window_t xwin{}; +#endif + }; +} +auto ::dux::win::close() -> void { + [[maybe_unused]] auto * const dux_restr dat = static_cast<::dux::windat *>(this->_dat); + ::dux::dbgprint(U"dux :: Closing window!\n"); +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::xcb_unmap_window(::dux::_inst.xconn,dat->xwin); + ::xcb_flush(::dux::_inst.xconn); +# endif + this->_isopen = false; + ::dux::_inst.numwin -= ::dux::uint16v(0x1); + ::dux::dbgprint(U"dux :: Current number of windows: $\n",::dux::_inst.numwin); + ::dux::dbgprint(U"dux :: Unsetting the SIGINT signal handler!\n"); + if (!::dux::_inst.numwin) { + ::dux::sighandl(::dux::sig::int_,*::dux::_inst.prevsiginthandl); + ::dux::_inst.siginthandlset = false; + return; + } + ::dux::dbgprint(U"dux :: An open window exists!\n"); +} +auto ::dux::win::crt(char const * const dux_restr _nm,::dux::uint16 const _w,::dux::uint16 const _h) -> ::dux::win { + ::dux::win win; + [[maybe_unused]] auto * const dux_restr dat = static_cast<::dux::windat *>(win._dat); +#if defined(dux_gfxproto_wlgl) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + dat->xwin = ::xcb_generate_id(::dux::_inst.xconn); + ::dux::uint32 valmask[] = { + XCB_EVENT_MASK_EXPOSURE, + }; + ::xcb_create_window(::dux::_inst.xconn,XCB_COPY_FROM_PARENT,dat->xwin,::dux::_inst.xscrn->root,::dux::uint16v(0x0),::dux::uint16v(0x0),_w,_h,::dux::uint16v(0x0),XCB_WINDOW_CLASS_INPUT_OUTPUT,::dux::_inst.xscrn->root_visual,::dux::uint32v(0x0),valmask); + ::xcb_map_window(::dux::_inst.xconn,dat->xwin); + ::xcb_flush(::dux::_inst.xconn); + win.renm(_nm); +#endif + ::dux::_inst.numwin += ::dux::uint16v(0x1); + ::dux::dbgprint(U"dux :: Current number of windows: $\n",::dux::_inst.numwin); + ::dux::_setsiginthandl(); + win._isopen = true; + return win; +} +auto ::dux::win::destr() noexcept -> void { + ::dux::dbgprint(U"dux :: Destroying window!\n"); + this->close(); + ::delete static_cast<::dux::windat *>(this->_dat); +} +auto ::dux::win::open() -> void { + [[maybe_unused]] auto * const dux_restr dat = static_cast<::dux::windat *>(this->_dat); + ::dux::dbgprint(U"dux :: Opening window!\n"); +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::xcb_map_window(::dux::_inst.xconn,dat->xwin); + ::xcb_flush(::dux::_inst.xconn); +# endif + ::dux::_inst.numwin += ::dux::uint16v(0x1); + ::dux::dbgprint(U"dux :: Current number of windows: $\n",::dux::_inst.numwin); + ::dux::_setsiginthandl(); + this->_isopen = true; +} +auto ::dux::win::pollevt() noexcept -> ::dux::opt<::dux::evt> { + ::dux::evt evt; + if (::dux::_inst.hassigint) [[unlikely]] { + evt.typ = ::dux::evttyp::quit; + ::dux::_inst.hassigint = false; + return evt; + } +#if defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + while (auto const xevt = ::xcb_poll_for_event(::dux::_inst.xconn)) { + switch (xevt->response_type & ~0x80) { + case XCB_CLIENT_MESSAGE: + evt.typ = ::dux::evttyp::quit; + break; + } + ::std::free(xevt); + return evt; + } +#endif + return evt; +} +auto ::dux::win::renm(char const * const dux_restr _nm) -> void { + [[maybe_unused]] auto * const dux_restr dat = static_cast<::dux::windat *>(this->_dat); +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::xcb_change_property(::dux::_inst.xconn,XCB_PROP_MODE_REPLACE,dat->xwin,XCB_ATOM_WM_NAME,XCB_ATOM_STRING,::dux::ubytev(0x8),static_cast<::dux::uint32>(::dux::cstrlen(_nm)),_nm); + ::xcb_flush(::dux::_inst.xconn); +# endif +} +auto ::dux::win::resz(::dux::uint16 const _w,::dux::uint16 const _h) -> void { + [[maybe_unused]] auto * const dux_restr dat = static_cast<::dux::windat *>(this->_dat); +#if defined(dux_gfxproto_wlgl) || defined(dux_gfxproto_wlvk) +#elif defined(dux_gfxproto_xgl) || defined(dux_gfxproto_xvk) + ::dux::uint32 const vals[] = { + _w, + _h, + }; + ::xcb_configure_window(::dux::_inst.xconn,dat->xwin,XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_WIDTH,vals); + ::xcb_flush(::dux::_inst.xconn); +#endif +} +::dux::win::win() : _dat(::new ::dux::windat) { +} +::dux::win::~win() noexcept { + if (this->_isopen) [[unlikely]] { + ::dux::dbgprint(U"dux :: Window was not closed!\n"); + ::dux::abrt(); + } +} |