diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 30aa626..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index a4f95c8..4540610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") set(OpenGL_GL_PREFERENCE "LEGACY") find_package(X11 REQUIRED) +find_package(Xrandr REQUIRED) find_package(OpenGL REQUIRED) find_package(GLUT REQUIRED) find_package(ZLIB REQUIRED) @@ -15,7 +16,7 @@ find_package(SDL REQUIRED) find_package(SDL_mixer REQUIRED) find_package(LZ4 REQUIRED) -include_directories(${X11_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} ${LZ4_INCLUDE_DIR} ${SDL_INCLUDE_DIRS} ${SDL_MIXER_INCLUDE_DIRS} .) +include_directories(${X11_INCLUDE_DIR} ${XRANDR_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} ${LZ4_INCLUDE_DIR} ${SDL_INCLUDE_DIRS} ${SDL_MIXER_INCLUDE_DIRS} .) add_executable( wallengine @@ -60,4 +61,4 @@ add_executable( wallpaperengine/sound.h ) -target_link_libraries(wallengine ${X11_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES}) \ No newline at end of file +target_link_libraries(wallengine ${X11_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES}) \ No newline at end of file diff --git a/CMakeModules/FindXrandr.cmake b/CMakeModules/FindXrandr.cmake new file mode 100644 index 0000000..3d8f1f2 --- /dev/null +++ b/CMakeModules/FindXrandr.cmake @@ -0,0 +1,78 @@ +# - try to find the Xrandr library +# +# Cache Variables: (probably not for direct use in your scripts) +# XRANDR_INCLUDE_DIR +# XRANDR_SOURCE_DIR +# XRANDR_LIBRARY +# +# Non-cache variables you might use in your CMakeLists.txt: +# XRANDR_FOUND +# XRANDR_INCLUDE_DIRS +# XRANDR_LIBRARIES +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) +# +# Original Author: +# 2014 Kevin M. Godby +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(XRANDR_ROOT_DIR + "${XRANDR_ROOT_DIR}" + CACHE + PATH + "Directory to search for Xrandr") + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_LIBXRANDR xrandr) +endif() + +find_library(XRANDR_LIBRARY + NAMES + Xrandr + PATHS + ${PC_LIBXRANDR_LIBRARY_DIRS} + ${PC_LIBXRANDR_LIBDIR} + HINTS + "${XRANDR_ROOT_DIR}" + PATH_SUFFIXES + lib + ) + +get_filename_component(_libdir "${XRANDR_LIBRARY}" PATH) + +find_path(XRANDR_INCLUDE_DIR + NAMES + Xrandr.h + PATHS + ${PC_LIBXRANDR_INCLUDE_DIRS} + ${PC_LIBXRANDR_INCLUDEDIR} + HINTS + "${_libdir}" + "${_libdir}/.." + "${XRANDR_ROOT_DIR}" + PATH_SUFFIXES + X11 + X11/extensions + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XRANDR + DEFAULT_MSG + XRANDR_LIBRARY + XRANDR_INCLUDE_DIR + ) + +if(XRANDR_FOUND) + list(APPEND XRANDR_LIBRARIES ${XRANDR_LIBRARY}) + list(APPEND XRANDR_INCLUDE_DIRS ${XRANDR_INCLUDE_DIR}) + mark_as_advanced(XRANDR_ROOT_DIR) +endif() + +mark_as_advanced(XRANDR_INCLUDE_DIR + XRANDR_LIBRARY) + diff --git a/README.md b/README.md index e3eef46..ba02a5d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Wallpaper Engine is a software designed by [Kristjan Skutta](https://store.steam - ZLIB - SDL - SDL_mixer +- X11 +- Xrandr # 5. How to use ## 5.1. Pre-requirements @@ -68,6 +70,14 @@ Uncompressed backgrounds are just plain folders including all the resources and ./wallengine --dir folder ``` +#### 5.4.3. Running as a screen's background +Only screens configured with the XRandr extension are supported. To specify the screen names (as reported from xrandr tool) just use the ```--screen-root``` switch. You can specify multiple screens at the same time, for example: +``` +./wallengine --screen-root HDMI-1 --screen-root DVI-D-1 +``` + +**IMPORTANT: Right now this doesn't work if there is anything drawing to the background (like a compositor, nautilus, etc)** + ###### Example background This was the first background to even be compatible with the software. And It's not 100% compatible yet. Both textures and shaders are properly loaded, but there are still particles missing. diff --git a/main.cpp b/main.cpp index 80d7c76..3a67206 100644 --- a/main.cpp +++ b/main.cpp @@ -8,12 +8,19 @@ #include #include +// support for randr extended screens +#include +#include + #include "wallpaperengine/shaders/compiler.h" #include "wallpaperengine/project.h" #include "wallpaperengine/irrlicht.h" #include "wallpaperengine/irr/CImageLoaderTEX.h" -int WinID = 0; +bool IsRootWindow = false; +std::vector Screens; +std::vector> Viewports; + irr::SIrrlichtCreationParameters _irr_params; irr::f32 g_Time = 0; @@ -25,7 +32,7 @@ int init_irrlicht() _irr_params.Bits = 16; // _irr_params.DeviceType = irr::EIDT_X11; _irr_params.DriverType = irr::video::EDT_OPENGL; - _irr_params.Doublebuffer = true; + _irr_params.Doublebuffer = false; _irr_params.EventReceiver = nullptr; _irr_params.Fullscreen = false; _irr_params.HandleSRGB = false; @@ -36,7 +43,55 @@ int init_irrlicht() _irr_params.WithAlphaChannel = false; _irr_params.ZBufferBits = 24; _irr_params.LoggingLevel = irr::ELL_DEBUG; - _irr_params.WindowId = reinterpret_cast (WinID); + + if (IsRootWindow == true) + { + Display* display = XOpenDisplay (NULL); + XRRScreenResources* screenResources = XRRGetScreenResources (display, DefaultRootWindow (display)); + + // there are some situations where xrandr returns null (like screen not using the extension) + if (screenResources != nullptr) + { + for (int i = 0; i < screenResources->noutput; i ++) + { + XRROutputInfo* info = XRRGetOutputInfo (display, screenResources, screenResources->outputs [i]); + + // there are some situations where xrandr returns null (like screen not using the extension) + if (info == nullptr) + continue; + + std::vector::iterator cur = Screens.begin (); + std::vector::iterator end = Screens.end (); + + for (; cur != end; cur ++) + { + if (info->connection == RR_Connected && strcmp (info->name, (*cur).c_str ()) == 0) + { + XRRCrtcInfo* crtc = XRRGetCrtcInfo (display, screenResources, info->crtc); + + std::cout << "Found requested screen: " << info->name << " -> " << crtc->x << "x" << crtc->y << ":" << crtc->width << "x" << crtc->height << std::endl; + + irr::core::rect viewport; + + viewport.UpperLeftCorner.X = crtc->x; + viewport.UpperLeftCorner.Y = crtc->y; + viewport.LowerRightCorner.X = crtc->x + crtc->width; + viewport.LowerRightCorner.Y = crtc->y + crtc->height; + + Viewports.push_back (viewport); + + XRRFreeCrtcInfo (crtc); + } + } + + XRRFreeOutputInfo (info); + } + + XRRFreeScreenResources (screenResources); + } + + _irr_params.WindowId = reinterpret_cast (DefaultRootWindow (display)); + } wp::irrlicht::device = irr::createDeviceEx (_irr_params); @@ -84,7 +139,7 @@ void print_help (const char* route) << " --silent\t\tMutes all the sound the wallpaper might produce" << std::endl << " --dir \tLoads an uncompressed background from the given " << std::endl << " --pkg \tLoads a scene.pkg file from the given " << std::endl - << " --win \tX Window ID to attach to" << std::endl; + << " --screen-root \tDisplay as screen's background" << std::endl; } int main (int argc, char* argv[]) @@ -96,26 +151,26 @@ int main (int argc, char* argv[]) int option_index = 0; static struct option long_options [] = { - {"win", required_argument, 0, 'w'}, - {"pkg", required_argument, 0, 'p'}, - {"dir", required_argument, 0, 'd'}, - {"silent", optional_argument, 0, 's'}, - {"help", optional_argument, 0, 'h'}, + {"screen-root", required_argument, 0, 'r'}, + {"pkg", required_argument, 0, 'p'}, + {"dir", required_argument, 0, 'd'}, + {"silent", optional_argument, 0, 's'}, + {"help", optional_argument, 0, 'h'}, {nullptr, 0, 0, 0} }; while (true) { - int c = getopt_long (argc, argv, "w:p:d:sh", long_options, &option_index); + int c = getopt_long (argc, argv, "r:p:d:sh", long_options, &option_index); if (c == -1) break; switch (c) { - case 'w': - if (optarg) - WinID = atoi (optarg); + case 'r': + IsRootWindow = true; + Screens.push_back (optarg); break; case 'p': @@ -141,8 +196,6 @@ int main (int argc, char* argv[]) } } - std::cout << "Initializing irrlicht to WindowID " << WinID << std::endl; - if (init_irrlicht()) { return 1; @@ -224,7 +277,16 @@ int main (int argc, char* argv[]) if (currentTime - lastTime > minimumTime) { - wp::video::renderer::render (); + std::vector>::iterator cur = Viewports.begin (); + std::vector>::iterator end = Viewports.end (); + + for (; cur != end; cur ++) + { + // change viewport to render to the correct portion of the display + wp::irrlicht::driver->setViewPort (*cur); + wp::video::renderer::render (); + } + lastTime = currentTime; } else diff --git a/wallpaperengine/video/renderer.cpp b/wallpaperengine/video/renderer.cpp index 4dbbd9e..8fe3fe9 100644 --- a/wallpaperengine/video/renderer.cpp +++ b/wallpaperengine/video/renderer.cpp @@ -43,7 +43,7 @@ namespace wp { if (wp::irrlicht::driver == nullptr) return; - wp::irrlicht::driver->beginScene(true, true, irr::video::SColor(0, 0, 0, 0)); + wp::irrlicht::driver->beginScene(false, true, irr::video::SColor(0, 0, 0, 0)); std::vector::const_iterator cur = s_nodes.begin (); std::vector::const_iterator end = s_nodes.end ();