diff options
author | Claudius Holeksa <mail@keldu.de> | 2023-05-23 01:38:07 +0200 |
---|---|---|
committer | Claudius Holeksa <mail@keldu.de> | 2023-05-23 01:38:07 +0200 |
commit | 5f2ca9a01d2e493e222bead7222613e050871928 (patch) | |
tree | cf758b9a91ed13e5f1f100f7111ee3f5ac9e64c8 | |
parent | 7f0440cc25fc3ebc711df9fb708a5bffe53bf784 (diff) |
c++: Changing approach to a more exposed variant
-rw-r--r-- | default.nix | 7 | ||||
-rw-r--r-- | src/window/.nix/derivation.nix | 3 | ||||
-rw-r--r-- | src/window/SConscript | 30 | ||||
-rw-r--r-- | src/window/SConstruct | 66 | ||||
-rw-r--r-- | src/window/device.h | 2 | ||||
-rw-r--r-- | src/window/window.h | 22 | ||||
-rw-r--r-- | src/window/xcb.cpp | 21 | ||||
-rw-r--r-- | src/window/xcb.h | 69 |
8 files changed, 204 insertions, 16 deletions
diff --git a/default.nix b/default.nix index 1f679d7..4fd2ab8 100644 --- a/default.nix +++ b/default.nix @@ -45,5 +45,12 @@ in rec { clang = pkgs.clang_15; clang-tools = pkgs.clang-tools_15; }; + + window = pkgs.callPackage src/window/.nix/derivation.nix { + inherit version; + inherit forstio; + clang = pkgs.clang_15; + clang-tools = pkgs.clang-tools_15; + }; }; } diff --git a/src/window/.nix/derivation.nix b/src/window/.nix/derivation.nix index cfa5894..77189f1 100644 --- a/src/window/.nix/derivation.nix +++ b/src/window/.nix/derivation.nix @@ -5,6 +5,7 @@ , clang-tools , version , forstio +, xorg }: let @@ -26,6 +27,8 @@ in stdenvNoCC.mkDerivation { forstio.core forstio.async forstio.io + xorg.libX11 + xorg.libxcb ]; outputs = ["out" "dev"]; diff --git a/src/window/SConscript b/src/window/SConscript index 789b3aa..bd830b9 100644 --- a/src/window/SConscript +++ b/src/window/SConscript @@ -9,8 +9,30 @@ Import('env') dir_path = Dir('.').abspath -env.sources += sorted(glob.glob(dir_path + "/*.cpp")) -env.headers += sorted(glob.glob(dir_path + "/*.h")) +# Environment for base library +window_env = env.Clone(); -env.gl_sources += sorted(glob.glob(dir_path + "/gl/*.cpp")) -env.gl_headers += sorted(glob.glob(dir_path + "/gl/*.h")) +window_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +window_env.headers = sorted(glob.glob(dir_path + "/*.h")) + +env.sources += window_env.sources; +env.headers += window_env.headers; + +## Shared lib +objects_shared = [] +window_env.add_source_files(objects_shared, window_env.sources, shared=True); +window_env.library_shared = window_env.SharedLibrary('#build/forstio-window', [objects_shared]); + +## Static lib +objects_static = [] +window_env.add_source_files(objects_static, window_env.sources, shared=False); +window_env.library_static = window_env.StaticLibrary('#build/forstio-window', [objects_static]); + +# Set Alias +env.Alias('library_window', [window_env.library_shared, window_env.library_static]); + +env.targets += ['library_window']; + +# Install +env.Install('$prefix/lib/', [window_env.library_shared, window_env.library_static]); +env.Install('$prefix/include/forstio/window/', [window_env.headers]); diff --git a/src/window/SConstruct b/src/window/SConstruct new file mode 100644 index 0000000..69c70eb --- /dev/null +++ b/src/window/SConstruct @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +import sys +import os +import os.path +import glob +import re + + +if sys.version_info < (3,): + def isbasestring(s): + return isinstance(s,basestring) +else: + def isbasestring(s): + return isinstance(s, (str,bytes)) + +def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""): + + if isbasestring(filetype): + dir_path = self.Dir('.').abspath + filetype = sorted(glob.glob(dir_path+"/"+filetype)) + + for path in filetype: + target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path ) + if shared: + target_name+='.os' + sources.append( self.SharedObject( target=target_name, source=path ) ) + else: + target_name+='.o' + sources.append( self.StaticObject( target=target_name, source=path ) ) + pass + +def isAbsolutePath(key, dirname, env): + assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,) + +env_vars = Variables( + args=ARGUMENTS +) + +env_vars.Add('prefix', + help='Installation target location of build results and headers', + default='/usr/local/', + validator=isAbsolutePath +) + +env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[], + CPPDEFINES=['SAW_UNIX'], + CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'], + LIBS=['forstio-core', 'forstio-io', 'forstio-async']) +env.__class__.add_source_files = add_kel_source_files +env.Tool('compilation_db'); +env.cdb = env.CompilationDatabase('compile_commands.json'); + +env.objects = []; +env.sources = []; +env.headers = []; +env.targets = []; + +Export('env') +SConscript('SConscript') + +env.Alias('cdb', env.cdb); +env.Alias('all', [env.targets]); +env.Default('all'); + +env.Alias('install', '$prefix') diff --git a/src/window/device.h b/src/window/device.h index 70a388e..2796d4d 100644 --- a/src/window/device.h +++ b/src/window/device.h @@ -8,6 +8,7 @@ #include "window.h" +/** namespace saw { class device { public: @@ -21,3 +22,4 @@ public: class io_provider; own<device> create_device(io_provider &provider); } // namespace saw +*/ diff --git a/src/window/window.h b/src/window/window.h index 216c866..a6baae1 100644 --- a/src/window/window.h +++ b/src/window/window.h @@ -1,7 +1,8 @@ #pragma once #include <forstio/async/async.h> -#include <forstio/common.h> +#include <forstio/core/common.h> +#include <forstio/codec/schema.h> #include <string_view> #include <variant> @@ -9,7 +10,23 @@ #include "video_mode.h" namespace saw { +namespace schema { +using WindowResize = Struct< + NamedMember<UInt32, "width">, + NamedMember<UInt32, "height"> +>; +using WindowEvents = Union< + NamedMember<WindowResize, "resize"> +>; +} +} +#ifdef SAW_UNIX_XCB +#include "xcb.h" +#endif + +/** +namespace saw { class window { public: class event { @@ -47,7 +64,7 @@ public: virtual void show() = 0; virtual void hide() = 0; - virtual const video_mode &videoMode() const = 0; + virtual const video_mode &get_video_mode() const = 0; virtual const std::string_view title() const = 0; virtual void resize(size_t width, size_t height) = 0; @@ -55,3 +72,4 @@ public: virtual conveyor<variant_event> on_event() = 0; }; } // namespace saw +*/ diff --git a/src/window/xcb.cpp b/src/window/xcb.cpp index 9a33bb8..c762945 100644 --- a/src/window/xcb.cpp +++ b/src/window/xcb.cpp @@ -9,6 +9,7 @@ #include "device.h" namespace saw { +class xcb_window; class xcb_device final : public device { public: ::Display *display; @@ -121,7 +122,7 @@ void xcb_device::handle_events() { auto find = windows.find(expose->window); if (find != windows.end()) { assert(find->second); - find->second->resizeevent(static_cast<size_t>(expose->x), + find->second->resize_event(static_cast<size_t>(expose->x), static_cast<size_t>(expose->y), static_cast<size_t>(expose->width), static_cast<size_t>(expose->height)); @@ -133,7 +134,7 @@ void xcb_device::handle_events() { auto find = windows.find(button->event); if (find != windows.end()) { assert(find->second); - find->second->mouseevent(button->event_x, button->event_y, + find->second->mouse_event(button->event_x, button->event_y, button->detail, false); } } break; @@ -143,7 +144,7 @@ void xcb_device::handle_events() { auto find = windows.find(button->event); if (find != windows.end()) { assert(find->second); - find->second->mouseevent(button->event_x, button->event_y, + find->second->mouse_event(button->event_x, button->event_y, button->detail, true); } } break; @@ -177,7 +178,7 @@ void xcb_device::handle_events() { auto find = windows.find(key->event); if (find != windows.end()) { assert(find->second); - find->second->keyboardevent(key->event_x, key->event_y, + find->second->keyboard_event(key->event_x, key->event_y, key->detail, repeat, repeat); } } break; @@ -187,7 +188,7 @@ void xcb_device::handle_events() { auto find = windows.find(key->event); if (find != windows.end()) { assert(find->second); - find->second->keyboardevent(key->event_x, key->event_y, + find->second->keyboard_event(key->event_x, key->event_y, key->detail, true, false); } } break; @@ -314,7 +315,7 @@ void xcb_window::hide() { xcb_unmap_window(device_.xcb_connection, xcb_window_); } -const video_mode &xcb_window::videoMode() const { return video_mode_; } +const video_mode &xcb_window::get_video_mode() const { return video_mode_; } const std::string_view xcb_window::title() const { return window_title_; } @@ -329,13 +330,13 @@ void xcb_window::resize(size_t width, size_t height) { video_mode_.height = height; } -conveyor<window::variant_event> xcb_window::onevent() { +conveyor<window::variant_event> xcb_window::on_event() { auto caf = new_conveyor_and_feeder<window::variant_event>(); event_feeder = std::move(caf.feeder); return std::move(caf.conveyor); } -void xcb_window::resizeevent(size_t x, size_t y, size_t width, size_t height) { +void xcb_window::resize_event(size_t x, size_t y, size_t width, size_t height) { (void)x; (void)y; /// @todo maybe include x and y? @@ -348,7 +349,7 @@ void xcb_window::resizeevent(size_t x, size_t y, size_t width, size_t height) { } } -void xcb_window::mouseevent(int16_t x, int16_t y, uint16_t state, +void xcb_window::mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed) { if (x < 0 || y < 0) { return; @@ -379,7 +380,7 @@ void xcb_window::mouse_move_event(int16_t x, int16_t y) { } } -void xcb_window::keyboardevent(int16_t x, int16_t y, uint32_t keycode, +void xcb_window::keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed, bool repeat) { if (x < 0 || y < 0) { return; diff --git a/src/window/xcb.h b/src/window/xcb.h new file mode 100644 index 0000000..61ed509 --- /dev/null +++ b/src/window/xcb.h @@ -0,0 +1,69 @@ +#pragma once + +#ifndef SAW_UNIX_XCB +#error "XCB is not supported" +#endif + +namespace saw { +class window; +class device { +private: + ::Display *display; + int screen; + + xcb_connection_t *xcb_connection; + xcb_screen_t *xcb_screen; + + own<input_stream> async_notifier; + conveyor_sink async_conveyor; + + std::map<xcb_window_t, window *> windows; + + std::vector<xcb_generic_event_t *> pending_events; +public: + device(::Display *display, int screen, xcb_connection_t *xcb_connection, + xcb_screen_t *xcb_screen, own<input_stream> && an); + + ~device(); + + void xcb_window_was_destroyed(xcb_window_t window_id); + void handle_events(); + + own<window> create_window(const video_mode& vid_mod, std::string_view title_view); + + void flush(); +}; + +class window { +private: + device *device_; + + xcb_window_t xcb_window_; + xcb_colormap_t xcb_colormap_; + + video_mode video_mode_; + std::string window_title_; + + own<conveyor_feeder<data<schema::WindowEvents>>> event_feeder = nullptr; +public: + window(device& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, std::string_view title_view_); + + ~window(); + + void show(); + void hide(); + + const video_mode& get_video_mode() const; + + const std::string_view get_title() const; + + void resize(uint64_t width, uint64_t height); + + conveyor<schema::WindowEvents> on_event(); + + void resize_event(uint64_t x, uint64_t y, uint64_t width, uint64_t height); + void mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed); + void mouse_move_event(int16_t x, int16_t y); + void keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed, bool repeat); +}; +} |