summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--default.nix7
-rw-r--r--src/window/.nix/derivation.nix3
-rw-r--r--src/window/SConscript30
-rw-r--r--src/window/SConstruct66
-rw-r--r--src/window/device.h2
-rw-r--r--src/window/window.h22
-rw-r--r--src/window/xcb.cpp21
-rw-r--r--src/window/xcb.h69
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);
+};
+}