godot/platform/linuxbsd/x11/display_server_x11.cpp

/**************************************************************************/
/*  display_server_x11.cpp                                                */
/**************************************************************************/
/*                         This file is part of:                          */
/*                             GODOT ENGINE                               */
/*                        https://godotengine.org                         */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
/*                                                                        */
/* Permission is hereby granted, free of charge, to any person obtaining  */
/* a copy of this software and associated documentation files (the        */
/* "Software"), to deal in the Software without restriction, including    */
/* without limitation the rights to use, copy, modify, merge, publish,    */
/* distribute, sublicense, and/or sell copies of the Software, and to     */
/* permit persons to whom the Software is furnished to do so, subject to  */
/* the following conditions:                                              */
/*                                                                        */
/* The above copyright notice and this permission notice shall be         */
/* included in all copies or substantial portions of the Software.        */
/*                                                                        */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
/**************************************************************************/

#include "display_server_x11.h"

#ifdef X11_ENABLED

#include "x11/detect_prime_x11.h"
#include "x11/key_mapping_x11.h"

#include "core/config/project_settings.h"
#include "core/math/math_funcs.h"
#include "core/string/print_string.h"
#include "core/string/ustring.h"
#include "drivers/png/png_driver_common.h"
#include "main/main.h"

#if defined(VULKAN_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif

#if defined(GLES3_ENABLED)
#include "drivers/gles3/rasterizer_gles3.h"
#endif

#include <dlfcn.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#undef CursorShape
#include <X11/XKBlib.h>

// ICCCM
#define WM_NormalState
#define WM_IconicState
// EWMH
#define _NET_WM_STATE_REMOVE
#define _NET_WM_STATE_ADD

// 2.2 is the first release with multitouch
#define XINPUT_CLIENT_VERSION_MAJOR
#define XINPUT_CLIENT_VERSION_MINOR

#define VALUATOR_ABSX
#define VALUATOR_ABSY
#define VALUATOR_PRESSURE
#define VALUATOR_TILTX
#define VALUATOR_TILTY

//#define DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
#ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
#define DEBUG_LOG_X11
#else
#define DEBUG_LOG_X11(...)
#endif

static const double abs_resolution_mult =;
static const double abs_resolution_range_mult =;

// Hints for X11 fullscreen
struct Hints {};

static String get_atom_name(Display *p_disp, Atom p_atom) {}

bool DisplayServerX11::has_feature(Feature p_feature) const {}

String DisplayServerX11::get_name() const {}

void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) {}

bool DisplayServerX11::_refresh_device_info() {}

void DisplayServerX11::_flush_mouse_motion() {}

#ifdef SPEECHD_ENABLED

bool DisplayServerX11::tts_is_speaking() const {}

bool DisplayServerX11::tts_is_paused() const {}

TypedArray<Dictionary> DisplayServerX11::tts_get_voices() const {}

void DisplayServerX11::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {}

void DisplayServerX11::tts_pause() {}

void DisplayServerX11::tts_resume() {}

void DisplayServerX11::tts_stop() {}

#endif

#ifdef DBUS_ENABLED

bool DisplayServerX11::is_dark_mode_supported() const {}

bool DisplayServerX11::is_dark_mode() const {}

void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) {}

Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {}

Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) {}

#endif

void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {}

DisplayServerX11::MouseMode DisplayServerX11::mouse_get_mode() const {}

void DisplayServerX11::warp_mouse(const Point2i &p_position) {}

Point2i DisplayServerX11::mouse_get_position() const {}

BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {}

void DisplayServerX11::clipboard_set(const String &p_text) {}

void DisplayServerX11::clipboard_set_primary(const String &p_text) {}

Bool DisplayServerX11::_predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg) {}

Bool DisplayServerX11::_predicate_clipboard_incr(Display *display, XEvent *event, XPointer arg) {}

String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const {}

Atom DisplayServerX11::_clipboard_get_image_target(Atom p_source, Window x11_window) const {}

String DisplayServerX11::_clipboard_get(Atom p_source, Window x11_window) const {}

String DisplayServerX11::clipboard_get() const {}

String DisplayServerX11::clipboard_get_primary() const {}

Ref<Image> DisplayServerX11::clipboard_get_image() const {}

bool DisplayServerX11::clipboard_has_image() const {}

Bool DisplayServerX11::_predicate_clipboard_save_targets(Display *display, XEvent *event, XPointer arg) {}

void DisplayServerX11::_clipboard_transfer_ownership(Atom p_source, Window x11_window) const {}

int DisplayServerX11::get_screen_count() const {}

int DisplayServerX11::get_primary_screen() const {}

int DisplayServerX11::get_keyboard_focus_screen() const {}

Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const {}

Point2i DisplayServerX11::screen_get_position(int p_screen) const {}

Size2i DisplayServerX11::screen_get_size(int p_screen) const {}

// A Handler to avoid crashing on non-fatal X errors by default.
//
// The original X11 error formatter `_XPrintDefaultError` is defined here:
// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/e45ca7b41dcd3ace7681d6897505f85d374640f2/src/XlibInt.c#L1322
// It is not exposed through the API, accesses X11 internals,
// and is much more complex, so this is a less complete simplified error X11 printer.
int default_window_error_handler(Display *display, XErrorEvent *error) {}

bool g_bad_window =;
int bad_window_error_handler(Display *display, XErrorEvent *error) {}

Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {}

int DisplayServerX11::screen_get_dpi(int p_screen) const {}

int get_image_errorhandler(Display *dpy, XErrorEvent *ev) {}

Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const {}

Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {}

float DisplayServerX11::screen_get_refresh_rate(int p_screen) const {}

#ifdef DBUS_ENABLED
void DisplayServerX11::screen_set_keep_on(bool p_enable) {}

bool DisplayServerX11::screen_is_kept_on() const {}
#endif

Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {}

DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) {}

void DisplayServerX11::show_window(WindowID p_id) {}

void DisplayServerX11::delete_sub_window(WindowID p_id) {}

int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {}

void DisplayServerX11::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {}

ObjectID DisplayServerX11::window_get_attached_instance_id(WindowID p_window) const {}

DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const Point2i &p_position) const {}

void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window) {}

void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {}

void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) {}

void DisplayServerX11::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {}

void DisplayServerX11::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {}

void DisplayServerX11::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {}

void DisplayServerX11::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {}

void DisplayServerX11::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {}

int DisplayServerX11::window_get_current_screen(WindowID p_window) const {}

void DisplayServerX11::gl_window_make_current(DisplayServer::WindowID p_window_id) {}

void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {}

void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent) {}

// Helper method. Assumes that the window id has already been checked and exists.
void DisplayServerX11::_update_size_hints(WindowID p_window) {}

Point2i DisplayServerX11::window_get_position(WindowID p_window) const {}

Point2i DisplayServerX11::window_get_position_with_decorations(WindowID p_window) const {}

void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p_window) {}

void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_window) {}

Size2i DisplayServerX11::window_get_max_size(WindowID p_window) const {}

void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_window) {}

Size2i DisplayServerX11::window_get_min_size(WindowID p_window) const {}

void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {}

Size2i DisplayServerX11::window_get_size(WindowID p_window) const {}

Size2i DisplayServerX11::window_get_size_with_decorations(WindowID p_window) const {}

// Just a helper to reduce code duplication in `window_is_maximize_allowed`
// and `_set_wm_maximized`.
bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_atom_name) const {}

bool DisplayServerX11::_window_minimize_check(WindowID p_window) const {}

bool DisplayServerX11::_window_fullscreen_check(WindowID p_window) const {}

void DisplayServerX11::_validate_mode_on_map(WindowID p_window) {}

bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {}

void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) {}

void DisplayServerX11::_set_wm_minimized(WindowID p_window, bool p_enabled) {}

void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive) {}

void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {}

DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) const {}

void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {}

bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) const {}

void DisplayServerX11::window_request_attention(WindowID p_window) {}

void DisplayServerX11::window_move_to_foreground(WindowID p_window) {}

DisplayServerX11::WindowID DisplayServerX11::get_focused_window() const {}

bool DisplayServerX11::window_is_focused(WindowID p_window) const {}

bool DisplayServerX11::window_can_draw(WindowID p_window) const {}

bool DisplayServerX11::can_any_window_draw() const {}

void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_window) {}

void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {}

Point2i DisplayServerX11::ime_get_selection() const {}

String DisplayServerX11::ime_get_text() const {}

void DisplayServerX11::cursor_set_shape(CursorShape p_shape) {}

DisplayServerX11::CursorShape DisplayServerX11::cursor_get_shape() const {}

void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {}

int DisplayServerX11::keyboard_get_layout_count() const {}

int DisplayServerX11::keyboard_get_current_layout() const {}

void DisplayServerX11::keyboard_set_current_layout(int p_index) {}

String DisplayServerX11::keyboard_get_layout_language(int p_index) const {}

String DisplayServerX11::keyboard_get_layout_name(int p_index) const {}

Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {}

Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {}
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {}

static Atom pick_target_from_list(Display *p_display, const Atom *p_list, int p_count) {}

static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p_t3) {}

void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) {}

void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo) {}

Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const {}

void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p_event) const {}

int DisplayServerX11::_xim_preedit_start_callback(::XIM xim, ::XPointer client_data,
		::XPointer call_data) {}

void DisplayServerX11::_xim_preedit_done_callback(::XIM xim, ::XPointer client_data,
		::XPointer call_data) {}

void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_data,
		::XIMPreeditDrawCallbackStruct *call_data) {}

void DisplayServerX11::_xim_preedit_caret_callback(::XIM xim, ::XPointer client_data,
		::XIMPreeditCaretCallbackStruct *call_data) {}

void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
		::XPointer call_data) {}

void DisplayServerX11::_window_changed(XEvent *event) {}

DisplayServer::WindowID DisplayServerX11::_get_focused_window_or_popup() const {}

void DisplayServerX11::_dispatch_input_events(const Ref<InputEvent> &p_event) {}

void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {}

void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_event) {}

void DisplayServerX11::_set_input_focus(Window p_window, int p_revert_to) {}

void DisplayServerX11::_poll_events_thread(void *ud) {}

Bool DisplayServerX11::_predicate_all_events(Display *display, XEvent *event, XPointer arg) {}

bool DisplayServerX11::_wait_for_events() const {}

void DisplayServerX11::_poll_events() {}

void DisplayServerX11::_check_pending_events(LocalVector<XEvent> &r_events) {}

DisplayServer::WindowID DisplayServerX11::window_get_active_popup() const {}

void DisplayServerX11::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {}

Rect2i DisplayServerX11::window_get_popup_safe_rect(WindowID p_window) const {}

void DisplayServerX11::popup_open(WindowID p_window) {}

void DisplayServerX11::popup_close(WindowID p_window) {}

bool DisplayServerX11::mouse_process_popups() {}

bool DisplayServerX11::_window_focus_check() {}

void DisplayServerX11::process_events() {}

void DisplayServerX11::release_rendering_thread() {}

void DisplayServerX11::swap_buffers() {}

void DisplayServerX11::_update_context(WindowData &wd) {}

void DisplayServerX11::set_context(Context p_context) {}

bool DisplayServerX11::is_window_transparency_available() const {}

void DisplayServerX11::set_native_icon(const String &p_filename) {}

bool g_set_icon_error =;
int set_icon_errorhandler(Display *dpy, XErrorEvent *ev) {}

void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {}

void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {}

DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {}

Vector<String> DisplayServerX11::get_rendering_drivers_func() {}

DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {}

DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {}

static bool _is_xim_style_supported(const ::XIMStyle &p_style) {}

static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMStyle &p_style_b) {}

DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {}

DisplayServerX11::~DisplayServerX11() {}

void DisplayServerX11::register_x11_driver() {}

#endif // X11 enabled