summaryrefslogtreecommitdiff
path: root/c++/window/xcb.cpp
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-12-04 12:18:14 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-12-04 12:18:14 +0100
commita14896f9ed209dd3f9597722e5a5697bd7dbf531 (patch)
tree089ca5cbbd206d1921f8f6b53292f5bc1902ca5c /c++/window/xcb.cpp
parent84ecdcbca9e55b1f57fbb832e12ff4fdbb86e7c9 (diff)
meta: Renamed folder containing source
Diffstat (limited to 'c++/window/xcb.cpp')
-rw-r--r--c++/window/xcb.cpp290
1 files changed, 0 insertions, 290 deletions
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_;
-}
-
-}
-}