diff options
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r-- | platform/x11/os_x11.cpp | 129 |
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 { |