diff options
Diffstat (limited to 'c++/window')
-rw-r--r-- | c++/window/.nix/derivation.nix | 34 | ||||
-rw-r--r-- | c++/window/SConscript | 38 | ||||
-rw-r--r-- | c++/window/SConstruct | 66 | ||||
-rw-r--r-- | c++/window/backends.h | 10 | ||||
-rw-r--r-- | c++/window/device.h | 18 | ||||
-rw-r--r-- | c++/window/linux_xcb.h | 5 | ||||
-rw-r--r-- | c++/window/old.dummy | 399 | ||||
-rw-r--r-- | c++/window/video_mode.h | 11 | ||||
-rw-r--r-- | c++/window/window.h | 79 | ||||
-rw-r--r-- | c++/window/xcb.cpp | 290 | ||||
-rw-r--r-- | c++/window/xcb.h | 105 |
11 files changed, 0 insertions, 1055 deletions
diff --git a/c++/window/.nix/derivation.nix b/c++/window/.nix/derivation.nix deleted file mode 100644 index 67a682c..0000000 --- a/c++/window/.nix/derivation.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ lib -, stdenv -, scons -, clang-tools -, version -, forstio -, xorg -}: - -let - -in stdenv.mkDerivation { - pname = "forstio-window"; - inherit version; - src = ./..; - - enableParallelBuilding = true; - - nativeBuildInputs = [ - scons - clang-tools - ]; - - buildInputs = [ - forstio.core - forstio.async - forstio.io - forstio.codec - xorg.libX11 - xorg.libxcb - ]; - - outputs = ["out" "dev"]; -} diff --git a/c++/window/SConscript b/c++/window/SConscript deleted file mode 100644 index bd830b9..0000000 --- a/c++/window/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/false - -import os -import os.path -import glob - - -Import('env') - -dir_path = Dir('.').abspath - -# Environment for base library -window_env = env.Clone(); - -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/c++/window/SConstruct b/c++/window/SConstruct deleted file mode 100644 index 05fc016..0000000 --- a/c++/window/SConstruct +++ /dev/null @@ -1,66 +0,0 @@ -#!/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', 'SAW_UNIX_XCB'], - CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'], - LIBS=['forstio-core', 'forstio-io', 'forstio-async', 'forstio-codec']) -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/c++/window/backends.h b/c++/window/backends.h deleted file mode 100644 index e129037..0000000 --- a/c++/window/backends.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace saw { -namespace gfx { -namespace backend { -struct linux_xcb {}; -struct wasm {}; -} -} -} diff --git a/c++/window/device.h b/c++/window/device.h deleted file mode 100644 index 7d3cdb1..0000000 --- a/c++/window/device.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "window.h" - -#include <forstio/async/async.h> -#include <forstio/core/common.h> -#include <forstio/codec/data.h> -#include <forstio/io/io.h> - -#include <string_view> -#include <variant> - -namespace saw { -namespace gfx { -template<typename T> -class device; -} -} diff --git a/c++/window/linux_xcb.h b/c++/window/linux_xcb.h deleted file mode 100644 index 65ff94d..0000000 --- a/c++/window/linux_xcb.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#ifdef SAW_UNIX_XCB -#include "xcb.h" -#endif diff --git a/c++/window/old.dummy b/c++/window/old.dummy deleted file mode 100644 index c762945..0000000 --- a/c++/window/old.dummy +++ /dev/null @@ -1,399 +0,0 @@ -#include <X11/Xlib-xcb.h> -#include <X11/Xlib.h> -#include <xcb/xcb.h> -#include <forstio/io/io.h> - -#include <map> -#include <vector> - -#include "device.h" - -namespace saw { -class xcb_window; -class xcb_device final : public device { -public: - ::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, xcb_window *> windows; - - std::vector<xcb_generic_event_t *> pending_events; - -public: - xcb_device(::Display *display, int screen, xcb_connection_t *xcb_connection, - xcb_screen_t *xcb_screen, own<input_stream> &&an); - ~xcb_device(); - - void window_destroyed(xcb_window_t window_id); - void handle_events(); - - own<xcb_window> create_xcb_window(const video_mode &mode, - std::string_view title_view, - int visual_id); - own<window> create_window(const video_mode &video_mode, - std::string_view title_view) override; - - void flush() override; -}; - -own<xcb_device> create_xcb_device(io_provider &provider); - -class xcb_window final : public window { -public: - xcb_device &device_; - - xcb_window_t xcb_window_; - xcb_colormap_t xcb_colormap_; - - video_mode video_mode_; - std::string window_title_; - - own<conveyor_feeder<window::variant_event>> event_feeder = nullptr; - -public: - xcb_window(xcb_device &dev, xcb_window_t xcb_win, - xcb_colormap_t xcb_colormap_, const video_mode &video_mode_, - std::string_view title_view_); - ~xcb_window(); - - void show() override; - void hide() override; - - const video_mode &get_video_mode() const override; - const std::string_view title() const override; - - void resize(size_t width, size_t height) override; - - conveyor<window::variant_event> on_event() override; - - void resize_event(size_t x, size_t y, size_t width, size_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); -}; - -xcb_device::xcb_device(::Display *display, int screen, - xcb_connection_t *xcb_connection, - xcb_screen_t *xcb_screen, own<input_stream> &&an) - : display{display}, screen{screen}, xcb_connection{xcb_connection}, - xcb_screen{xcb_screen}, async_notifier{std::move(an)}, - async_conveyor{async_notifier->read_ready() - .then([this]() { handle_events(); }) - .sink()} {} - -xcb_device::~xcb_device() { - if (display) { - xcb_flush(xcb_connection); - ::XCloseDisplay(display); - } -} - -void xcb_device::window_destroyed(xcb_window_t window_id) { - windows.erase(window_id); -} - -void xcb_device::handle_events() { - while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection)) { - pending_events.push_back(event); - } - for (size_t i = 0; i < pending_events.size(); ++i) { - xcb_generic_event_t *event = pending_events.at(i); - switch (event->response_type & ~0x80) { - case XCB_MOTION_NOTIFY: { - xcb_motion_notify_event_t *motion = - reinterpret_cast<xcb_motion_notify_event_t *>(event); - auto find = windows.find(motion->event); - if (find != windows.end()) { - assert(find->second); - find->second->mouse_move_event(motion->event_x, - motion->event_y); - } - } break; - case XCB_EXPOSE: { - xcb_expose_event_t *expose = - reinterpret_cast<xcb_expose_event_t *>(event); - auto find = windows.find(expose->window); - if (find != windows.end()) { - assert(find->second); - 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)); - } - } break; - case XCB_BUTTON_RELEASE: { - xcb_button_release_event_t *button = - reinterpret_cast<xcb_button_release_event_t *>(event); - auto find = windows.find(button->event); - if (find != windows.end()) { - assert(find->second); - find->second->mouse_event(button->event_x, button->event_y, - button->detail, false); - } - } break; - case XCB_BUTTON_PRESS: { - xcb_button_press_event_t *button = - reinterpret_cast<xcb_button_press_event_t *>(event); - auto find = windows.find(button->event); - if (find != windows.end()) { - assert(find->second); - find->second->mouse_event(button->event_x, button->event_y, - button->detail, true); - } - } break; - case XCB_KEY_RELEASE: { - xcb_key_release_event_t *key = - reinterpret_cast<xcb_key_release_event_t *>(event); - - bool repeat = false; - /* - * Peek into future events - */ - for (size_t j = i + 1; j < pending_events.size(); ++j) { - xcb_generic_event_t *f_ev = pending_events.at(j); - - if ((f_ev->response_type & ~0x80) == XCB_KEY_PRESS) { - xcb_key_press_event_t *f_key = - reinterpret_cast<xcb_key_press_event_t *>(f_ev); - - if (key->detail == f_key->detail && - key->event == f_key->event) { - auto iterator = pending_events.begin() + j; - assert(iterator != pending_events.end()); - free(*iterator); - pending_events.erase(iterator); - repeat = true; - break; - } - } - } - - auto find = windows.find(key->event); - if (find != windows.end()) { - assert(find->second); - find->second->keyboard_event(key->event_x, key->event_y, - key->detail, repeat, repeat); - } - } break; - case XCB_KEY_PRESS: { - xcb_key_press_event_t *key = - reinterpret_cast<xcb_key_press_event_t *>(event); - auto find = windows.find(key->event); - if (find != windows.end()) { - assert(find->second); - find->second->keyboard_event(key->event_x, key->event_y, - key->detail, true, false); - } - } break; - default: - break; - } - } - - for (xcb_generic_event_t *event : pending_events) { - free(event); - } - pending_events.clear(); -} - -own<xcb_window> xcb_device::create_xcb_window(const video_mode &video_mode, - std::string_view title_view, - int visual_id) { - assert(xcb_screen); - assert(xcb_connection); - - xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection); - xcb_window_t xcb_window = xcb_generate_id(xcb_connection); - - xcb_create_colormap(xcb_connection, XCB_COLORMAP_ALLOC_NONE, xcb_colormap, - xcb_screen->root, visual_id); - - uint32_t eventmask = - XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_BUTTON_MOTION; - uint32_t valuelist[] = {eventmask, xcb_colormap, 0}; - uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; - - xcb_create_window(xcb_connection, XCB_COPY_FROM_PARENT, xcb_window, - xcb_screen->root, 0, 0, video_mode.width, - video_mode.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - visual_id, valuemask, valuelist); - - xcb_change_property(xcb_connection, XCB_PROP_MODE_REPLACE, xcb_window, - XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(), - title_view.data()); - - xcb_flush(xcb_connection); - auto window = heap<class xcb_window>(*this, xcb_window, xcb_colormap, - video_mode, title_view); - windows[xcb_window] = window.get(); - - return window; -} - -own<window> xcb_device::create_window(const video_mode &video_mode, - std::string_view title_view) { - assert(xcb_screen); - return create_xcb_window(video_mode, title_view, xcb_screen->root_visual); -} - -void xcb_device::flush() { - assert(xcb_connection); - xcb_flush(xcb_connection); -} - -own<xcb_device> create_xcb_device(io_provider &provider) { - ::Display *display = ::XOpenDisplay(nullptr); - if (!display) { - /// @todo log errors - return nullptr; - } - - int screen = ::XDefaultScreen(display); - - xcb_connection_t *xcb_connection = ::XGetXCBConnection(display); - if (!xcb_connection) { - /// @todo log errors - ::XCloseDisplay(display); - return nullptr; - } - - int fd = xcb_get_file_descriptor(xcb_connection); - - own<input_stream> fd_wrapped = provider.wrap_input_fd(fd); - if (!fd_wrapped) { - ::XCloseDisplay(display); - return nullptr; - } - - ::XSetEventQueueOwner(display, XCBOwnsEventQueue); - - xcb_screen_iterator_t screen_iter = - xcb_setup_roots_iterator(xcb_get_setup(xcb_connection)); - for (int screen_i = screen; screen_iter.rem && screen_i > 0; - --screen_i, xcb_screen_next(&screen_iter)) - ; - - xcb_screen_t *xcb_screen = screen_iter.data; - - return heap<xcb_device>(display, screen, xcb_connection, xcb_screen, - std::move(fd_wrapped)); -} - -own<device> createdevice(io_provider &provider) { - return create_xcb_device(provider); -} - -xcb_window::xcb_window(xcb_device &dev, xcb_window_t xcb_win, - xcb_colormap_t xcb_colmap, const video_mode &vid_mode, - std::string_view title_view_) - : device_{dev}, xcb_window_{xcb_win}, xcb_colormap_{xcb_colmap}, - video_mode_{vid_mode}, window_title_{title_view_} {} - -xcb_window::~xcb_window() { - device_.window_destroyed(xcb_window_); - xcb_destroy_window(device_.xcb_connection, xcb_window_); - device_.flush(); -} - -void xcb_window::show() { - assert(device_.xcb_connection); - xcb_map_window(device_.xcb_connection, xcb_window_); -} - -void xcb_window::hide() { - assert(device_.xcb_connection); - xcb_unmap_window(device_.xcb_connection, xcb_window_); -} - -const video_mode &xcb_window::get_video_mode() const { return video_mode_; } - -const std::string_view xcb_window::title() const { return window_title_; } - -void xcb_window::resize(size_t width, size_t height) { - const uint32_t values[2] = {static_cast<uint32_t>(width), - static_cast<uint32_t>(height)}; - - xcb_configure_window(device_.xcb_connection, xcb_window_, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - values); - video_mode_.width = width; - video_mode_.height = height; -} - -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::resize_event(size_t x, size_t y, size_t width, size_t height) { - (void)x; - (void)y; - /// @todo maybe include x and y? - video_mode_.width = width; - video_mode_.height = height; - - if (event_feeder) { - event_feeder->feed( - window::variant_event{window::event::resize{width, height}}); - } -} - -void xcb_window::mouse_event(int16_t x, int16_t y, uint16_t state, - bool pressed) { - if (x < 0 || y < 0) { - return; - } - uint32_t ux = static_cast<uint32_t>(x); - uint32_t uy = static_cast<uint32_t>(y); - if (ux >= video_mode_.width || uy >= video_mode_.height) { - return; - } - if (event_feeder) { - event_feeder->feed(window::variant_event{ - window::event::mouse{state, pressed, ux, uy}}); - } -} - -void xcb_window::mouse_move_event(int16_t x, int16_t y) { - if (x < 0 || y < 0) { - return; - } - uint32_t ux = static_cast<uint32_t>(x); - uint32_t uy = static_cast<uint32_t>(y); - if (ux >= video_mode_.width || uy >= video_mode_.height) { - return; - } - if (event_feeder) { - event_feeder->feed( - window::variant_event{window::event::mouse_move{ux, uy}}); - } -} - -void xcb_window::keyboard_event(int16_t x, int16_t y, uint32_t keycode, - bool pressed, bool repeat) { - if (x < 0 || y < 0) { - return; - } - uint32_t ux = static_cast<uint32_t>(x); - uint32_t uy = static_cast<uint32_t>(y); - if (ux >= video_mode_.width || uy >= video_mode_.height) { - return; - } - if (event_feeder) { - event_feeder->feed(window::variant_event{ - window::event::keyboard{keycode, keycode, pressed, repeat}}); - } -} - -} // namespace saw diff --git a/c++/window/video_mode.h b/c++/window/video_mode.h deleted file mode 100644 index a8f1695..0000000 --- a/c++/window/video_mode.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include <cstddef> - -namespace saw { -class video_mode { -public: - size_t width = 64; - size_t height = 64; -}; -} // namespace saw diff --git a/c++/window/window.h b/c++/window/window.h deleted file mode 100644 index 36786de..0000000 --- a/c++/window/window.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include "video_mode.h" - -#include <forstio/async/async.h> -#include <forstio/core/common.h> -#include <forstio/codec/schema.h> - -#include <string_view> -#include <variant> - -namespace saw { -namespace gfx { -namespace schema { -using namespace saw::schema; -using WindowResize = Struct< - Member<UInt32, "width">, - Member<UInt32, "height"> ->; -using WindowEvents = Union< - Member<WindowResize, "resize"> ->; -} - -template<typename T> -class window; -} -} - -#include "linux_xcb.h" - -/** -namespace saw { -class window { -public: - class event { - public: - struct resize { - size_t width; - size_t height; - }; - - struct keyboard { - uint32_t key; - uint32_t scan; - bool pressed; - bool repeat; - }; - - struct mouse { - uint16_t button_mask; - bool pressed; - uint32_t x; - uint32_t y; - }; - - struct mouse_move { - uint32_t x; - uint32_t y; - }; - }; - - using variant_event = std::variant<event::resize, event::keyboard, - event::mouse, event::mouse_move>; - - virtual ~window() = default; - - virtual void show() = 0; - virtual void hide() = 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; - - virtual conveyor<variant_event> on_event() = 0; -}; -} // namespace saw -*/ diff --git a/c++/window/xcb.cpp b/c++/window/xcb.cpp deleted file mode 100644 index 1b804ba..0000000 --- a/c++/window/xcb.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#ifndef SAW_UNIX_XCB -#error "XCB is not supported" -#endif - -#include "xcb.h" - -namespace saw { -namespace gfx { -device<backend::linux_xcb>::device(::Display* disp, int screen, xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, own<input_stream>&& an): - display_{disp}, screen_{screen}, xcb_connection_{xcb_connection}, xcb_screen_{xcb_screen}, async_notifier_{std::move(an)}, - async_conveyor_{async_notifier_->read_ready() - .then([this]() { handle_events(); }) - .sink()} {} - -device<backend::linux_xcb>::~device(){ - if (display_) { - xcb_flush(xcb_connection_); - ::XCloseDisplay(display_); - } -} - -void device<backend::linux_xcb>::xcb_window_was_destroyed(xcb_window_t window_id){ - windows_.erase(window_id); -} - -void device<backend::linux_xcb>::handle_events(){ - while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection_)) { - pending_events_.push_back(event); - } - for (size_t i = 0; i < pending_events_.size(); ++i) { - xcb_generic_event_t *event = pending_events_.at(i); - switch (event->response_type & ~0x80) { - case XCB_MOTION_NOTIFY: { - xcb_motion_notify_event_t *motion = - reinterpret_cast<xcb_motion_notify_event_t *>(event); - auto find = windows_.find(motion->event); - if (find != windows_.end()) { - assert(find->second); - find->second->mouse_move_event(motion->event_x, - motion->event_y); - } - } break; - case XCB_EXPOSE: { - xcb_expose_event_t *expose = - reinterpret_cast<xcb_expose_event_t *>(event); - auto find = windows_.find(expose->window); - if (find != windows_.end()) { - assert(find->second); - 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)); - } - } break; - case XCB_BUTTON_RELEASE: { - xcb_button_release_event_t *button = - reinterpret_cast<xcb_button_release_event_t *>(event); - auto find = windows_.find(button->event); - if (find != windows_.end()) { - assert(find->second); - find->second->mouse_event(button->event_x, button->event_y, - button->detail, false); - } - } break; - case XCB_BUTTON_PRESS: { - xcb_button_press_event_t *button = - reinterpret_cast<xcb_button_press_event_t *>(event); - auto find = windows_.find(button->event); - if (find != windows_.end()) { - assert(find->second); - find->second->mouse_event(button->event_x, button->event_y, - button->detail, true); - } - } break; - case XCB_KEY_RELEASE: { - xcb_key_release_event_t *key = - reinterpret_cast<xcb_key_release_event_t *>(event); - - bool repeat = false; - /* - * Peek into future events - */ - for (size_t j = i + 1; j < pending_events_.size(); ++j) { - xcb_generic_event_t *f_ev = pending_events_.at(j); - - if ((f_ev->response_type & ~0x80) == XCB_KEY_PRESS) { - xcb_key_press_event_t *f_key = - reinterpret_cast<xcb_key_press_event_t *>(f_ev); - - if (key->detail == f_key->detail && - key->event == f_key->event) { - auto iterator = pending_events_.begin() + j; - assert(iterator != pending_events_.end()); - free(*iterator); - pending_events_.erase(iterator); - repeat = true; - break; - } - } - } - - auto find = windows_.find(key->event); - if (find != windows_.end()) { - assert(find->second); - find->second->keyboard_event(key->event_x, key->event_y, - key->detail, repeat, repeat); - } - } break; - case XCB_KEY_PRESS: { - xcb_key_press_event_t *key = - reinterpret_cast<xcb_key_press_event_t *>(event); - auto find = windows_.find(key->event); - if (find != windows_.end()) { - assert(find->second); - find->second->keyboard_event(key->event_x, key->event_y, - key->detail, true, false); - } - } break; - default: - break; - } - } - - for (xcb_generic_event_t *event : pending_events_) { - free(event); - } - pending_events_.clear(); -} - -own<window<backend::linux_xcb>> device<backend::linux_xcb>::create_xcb_window(const video_mode &vid_mode, - std::string_view title_view, - int visual_id) { - assert(xcb_screen_); - assert(xcb_connection_); - - xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection_); - xcb_window_t xcb_window = xcb_generate_id(xcb_connection_); - - xcb_create_colormap(xcb_connection_, XCB_COLORMAP_ALLOC_NONE, xcb_colormap, - xcb_screen_->root, visual_id); - - uint32_t eventmask = - XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_BUTTON_MOTION; - uint32_t valuelist[] = {eventmask, xcb_colormap, 0}; - uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; - - xcb_create_window(xcb_connection_, XCB_COPY_FROM_PARENT, xcb_window, - xcb_screen_->root, 0, 0, vid_mode.width, - vid_mode.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - visual_id, valuemask, valuelist); - - xcb_change_property(xcb_connection_, XCB_PROP_MODE_REPLACE, xcb_window, - XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(), - title_view.data()); - - xcb_flush(xcb_connection_); - auto win = heap<window<backend::linux_xcb>>(*this, xcb_window, xcb_colormap, - vid_mode, title_view); - // Insert into map - windows_[xcb_window] = win.get(); - - return win; -} - -own<window<backend::linux_xcb>> device<backend::linux_xcb>::create_window(const video_mode& vid_mode, std::string_view title_view){ - assert(xcb_screen_); - return create_xcb_window(vid_mode, title_view, xcb_screen_->root_visual); -} - -void device<backend::linux_xcb>::flush(){ - assert(xcb_connection_); - xcb_flush(xcb_connection_); -} - -error_or<own<device<backend::linux_xcb>>> create_xcb_device(io_provider& provider){ - ::Display *display = ::XOpenDisplay(nullptr); - if (!display) { - /// @todo log errors - return make_error<err::critical>(); - } - - int screen = ::XDefaultScreen(display); - - xcb_connection_t *xcb_connection = ::XGetXCBConnection(display); - if (!xcb_connection) { - /// @todo log errors - ::XCloseDisplay(display); - return make_error<err::critical>(); - } - - int fd = xcb_get_file_descriptor(xcb_connection); - - own<input_stream> fd_wrapped = provider.wrap_input_fd(fd); - if (!fd_wrapped) { - ::XCloseDisplay(display); - return make_error<err::critical>(); - } - - ::XSetEventQueueOwner(display, XCBOwnsEventQueue); - - xcb_screen_iterator_t screen_iter = - xcb_setup_roots_iterator(xcb_get_setup(xcb_connection)); - for (int screen_i = screen; screen_iter.rem && screen_i > 0; - --screen_i, xcb_screen_next(&screen_iter)) - ; - - xcb_screen_t *xcb_screen = screen_iter.data; - - return heap<device<backend::linux_xcb>>(display, screen, xcb_connection, xcb_screen, std::move(fd_wrapped)); -} - -window<backend::linux_xcb>::window(device<backend::linux_xcb>& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, const std::string_view& title_view_): - device_{&dev_}, - xcb_window_{xcb_win}, - xcb_colormap_{xcb_colormap_}, - video_mode_{vid_mode_}, - window_title_{title_view_} -{} - -window<backend::linux_xcb>::~window(){ - assert(device_); - device_->xcb_window_was_destroyed(xcb_window_); - xcb_destroy_window(device_->xcb_connection_, xcb_window_); - device_->flush(); -} - -void window<backend::linux_xcb>::show(){ - assert(device_->xcb_connection_); - xcb_map_window(device_->xcb_connection_, xcb_window_); -} - -void window<backend::linux_xcb>::hide(){ - assert(device_->xcb_connection_); - xcb_unmap_window(device_->xcb_connection_, xcb_window_); -} - -const video_mode& window<backend::linux_xcb>::get_video_mode() const { - return video_mode_; -} - -const std::string_view window<backend::linux_xcb>::get_title() const { - return window_title_; -} - -void window<backend::linux_xcb>::resize(uint64_t w, uint64_t h){ - const uint32_t values[2] = { - static_cast<uint32_t>(w), - static_cast<uint32_t>(h) - }; - - xcb_configure_window(device_->xcb_connection_, xcb_window_, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - values); - - video_mode_.width = w; - video_mode_.height = h; -} - -conveyor<data<schema::WindowEvents>> window<backend::linux_xcb>::on_event() { - auto caf = new_conveyor_and_feeder<data<schema::WindowEvents>>(); - event_feeder = std::move(caf.feeder); - return std::move(caf.conveyor); -} - -void window<backend::linux_xcb>::resize_event(uint64_t x, uint64_t y, uint64_t width, uint64_t height){ - /// @todo implement - assert(false); -} -void window<backend::linux_xcb>::mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed){ - /// @todo implement - assert(false); -} -void window<backend::linux_xcb>::mouse_move_event(int16_t x, int16_t y){ - /// @todo implement - assert(false); -} -void window<backend::linux_xcb>::keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed, bool repeat){ - /// @todo implement - assert(false); -} - -xcb_window_t window<backend::linux_xcb>::get_xcb_window_handle() const{ - return xcb_window_; -} - -} -} diff --git a/c++/window/xcb.h b/c++/window/xcb.h deleted file mode 100644 index a2a9b0b..0000000 --- a/c++/window/xcb.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#ifndef SAW_UNIX_XCB -#error "XCB is not supported" -#endif - -#include "backends.h" -#include "device.h" -#include "window.h" - -#include <map> - -#include <X11/Xlib-xcb.h> -#include <X11/Xlib.h> - -namespace saw { -namespace gfx { -template<typename T> -class window; - -template<typename T> -class device; - -template<> -class device<backend::linux_xcb> final { -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<backend::linux_xcb> *> windows_; - - std::vector<xcb_generic_event_t *> pending_events_; - - friend class window<backend::linux_xcb>; -public: - own<window<backend::linux_xcb>> create_xcb_window(const video_mode& vid_mod, std::string_view title_view, int visual_id); - void xcb_window_was_destroyed(xcb_window_t window_id); -public: - device(::Display *display, int screen, xcb_connection_t *xcb_connection, - xcb_screen_t *xcb_screen, own<input_stream> && an); - - ~device(); - - void handle_events(); - - own<window<backend::linux_xcb>> create_window(const video_mode& vid_mod, std::string_view title_view); - - void flush(); - - // XCB specific info for other classes - ::Display* get_xcb_display() { - return display_; - } - - int get_xcb_screen() const { - return screen_; - } -}; - -error_or<own<device<backend::linux_xcb>>> create_xcb_device(io_provider& provider); - -template<> -class window<backend::linux_xcb> final { -private: - device<backend::linux_xcb> *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<backend::linux_xcb>& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, const 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<data<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); - - // XCB specific things - xcb_window_t get_xcb_window_handle() const; -}; -} -} |