summaryrefslogtreecommitdiff
path: root/platform/x11/os_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r--platform/x11/os_x11.cpp129
1 files changed, 78 insertions, 51 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 2d8e32137f..338d13410f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "os_x11.h"
+#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
#include "errno.h"
#include "key_mapping_x11.h"
+#include "os/dir_access.h"
#include "print_string.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
@@ -75,25 +77,6 @@
#include <X11/XKBlib.h>
-int OS_X11::get_video_driver_count() const {
- return 1;
-}
-
-const char *OS_X11::get_video_driver_name(int p_driver) const {
- return "GLES3";
-}
-
-int OS_X11::get_audio_driver_count() const {
- return AudioDriverManager::get_driver_count();
-}
-
-const char *OS_X11::get_audio_driver_name(int p_driver) const {
-
- AudioDriver *driver = AudioDriverManager::get_driver(p_driver);
- ERR_FAIL_COND_V(!driver, "");
- return AudioDriverManager::get_driver(p_driver)->get_name();
-}
-
void OS_X11::initialize_core() {
crash_handler.initialize();
@@ -282,12 +265,25 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
//print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height));
#if defined(OPENGL_ENABLED)
- context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, true));
- context_gl->initialize();
+ ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE;
- RasterizerGLES3::register_config();
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+ }
- RasterizerGLES3::make_current();
+ context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+ context_gl->initialize();
+
+ switch (opengl_api_type) {
+ case ContextGL_X11::GLES_2_0_COMPATIBLE: {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } break;
+ case ContextGL_X11::GLES_3_0_COMPATIBLE: {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ } break;
+ }
context_gl->set_use_vsync(current_videomode.use_vsync);
@@ -730,6 +726,16 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con
}
void OS_X11::set_wm_fullscreen(bool p_enabled) {
+ if (p_enabled && !get_borderless_window()) {
+ // remove decorations if the window is not already borderless
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = 0;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+ }
+
if (p_enabled && !is_window_resizable()) {
// Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
XSizeHints *xsh;
@@ -740,7 +746,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
XFree(xsh);
}
- // Using EWMH -- Extened Window Manager Hints
+ // Using EWMH -- Extended Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
@@ -1182,6 +1188,7 @@ bool OS_X11::is_window_maximized() const {
unsigned long len;
unsigned long remaining;
unsigned char *data = NULL;
+ bool retval = false;
int result = XGetWindowProperty(
x11_display,
@@ -1210,13 +1217,15 @@ bool OS_X11::is_window_maximized() const {
if (atoms[i] == wm_max_vert)
found_wm_max_vert = true;
- if (found_wm_max_horz && found_wm_max_vert)
- return true;
+ if (found_wm_max_horz && found_wm_max_vert) {
+ retval = true;
+ break;
+ }
}
- XFree(atoms);
}
- return false;
+ XFree(data);
+ return retval;
}
void OS_X11::set_window_always_on_top(bool p_enabled) {
@@ -2366,11 +2375,11 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
Ref<Texture> texture = p_cursor;
Ref<Image> image = texture->get_data();
- ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+ ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
// Create the cursor structure
XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height());
- XcursorUInt image_size = 32 * 32;
+ XcursorUInt image_size = texture->get_width() * texture->get_height();
XcursorDim size = sizeof(XcursorPixel) * image_size;
cursor_image->version = 1;
@@ -2384,10 +2393,10 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image->lock();
for (XcursorPixel index = 0; index < image_size; index++) {
- int column_index = floor(index / 32);
- int row_index = index % 32;
+ int row_index = floor(index / texture->get_width());
+ int column_index = index % texture->get_width();
- *(cursor_image->pixels + index) = image->get_pixel(row_index, column_index).to_argb32();
+ *(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32();
}
image->unlock();
@@ -2585,48 +2594,66 @@ static String get_mountpoint(const String &p_path) {
}
Error OS_X11::move_to_trash(const String &p_path) {
- String trashcan = "";
+ String trash_can = "";
String mnt = get_mountpoint(p_path);
+ // If there is a directory "[Mountpoint]/.Trash-[UID]/files", use it as the trash can.
if (mnt != "") {
String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
struct stat s;
if (!stat(path.utf8().get_data(), &s)) {
- trashcan = path;
+ trash_can = path;
}
}
- if (trashcan == "") {
+ // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash/files" as the trash can.
+ if (trash_can == "") {
char *dhome = getenv("XDG_DATA_HOME");
if (dhome) {
- trashcan = String(dhome) + "/Trash/files";
+ trash_can = String(dhome) + "/Trash/files";
}
}
- if (trashcan == "") {
+ // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash/files" as the trash can.
+ if (trash_can == "") {
char *home = getenv("HOME");
if (home) {
- trashcan = String(home) + "/.local/share/Trash/files";
+ trash_can = String(home) + "/.local/share/Trash/files";
}
}
- if (trashcan == "") {
- ERR_PRINTS("move_to_trash: Could not determine trashcan location");
+ // Issue an error if none of the previous locations is appropriate for the trash can.
+ if (trash_can == "") {
+ ERR_PRINTS("move_to_trash: Could not determine the trash can location");
return FAILED;
}
- List<String> args;
- args.push_back("-p");
- args.push_back(trashcan);
- Error err = execute("mkdir", args, true);
- if (err == OK) {
- List<String> args2;
- args2.push_back(p_path);
- args2.push_back(trashcan);
- err = execute("mv", args2, true);
+ // Create needed directories for decided trash can location.
+ DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error err = dir_access->make_dir_recursive(trash_can);
+ memdelete(dir_access);
+
+ // Issue an error if trash can is not created proprely.
+ if (err != OK) {
+ ERR_PRINTS("move_to_trash: Could not create the trash can \"" + trash_can + "\"");
+ return err;
}
- return err;
+ // The trash can is successfully created, now move the given resource to it.
+ // Do not use DirAccess:rename() because it can't move files across multiple mountpoints.
+ List<String> mv_args;
+ mv_args.push_back(p_path);
+ mv_args.push_back(trash_can);
+ int retval;
+ err = execute("mv", mv_args, true, NULL, NULL, &retval);
+
+ // Issue an error if "mv" failed to move the given resource to the trash can.
+ if (err != OK || retval != 0) {
+ ERR_PRINTS("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\"");
+ return FAILED;
+ }
+
+ return OK;
}
OS::LatinKeyboardVariant OS_X11::get_latin_keyboard_variant() const {