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 ();