소스 검색

~ Support for displaying on background of specific screens instead of displaying on top, please carefuly read the README.md before using

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
Alexis Maiquez 7 년 전
부모
커밋
82c187fa76
6개의 변경된 파일과 170개의 추가작업 그리고 48개의 파일을 삭제
  1. 0 29
      .idea/codeStyles/Project.xml
  2. 3 2
      CMakeLists.txt
  3. 78 0
      CMakeModules/FindXrandr.cmake
  4. 10 0
      README.md
  5. 78 16
      main.cpp
  6. 1 1
      wallpaperengine/video/renderer.cpp

+ 0 - 29
.idea/codeStyles/Project.xml

@@ -1,29 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <code_scheme name="Project" version="173">
-    <Objective-C-extensions>
-      <file>
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
-      </file>
-      <class>
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
-      </class>
-      <extensions>
-        <pair source="cpp" header="h" fileNamingConvention="NONE" />
-        <pair source="c" header="h" fileNamingConvention="NONE" />
-      </extensions>
-    </Objective-C-extensions>
-  </code_scheme>
-</component>

+ 3 - 2
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})
+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})

+ 78 - 0
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 <kevin@godby.org>
+#
+# 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)
+

+ 10 - 0
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.
 

+ 78 - 16
main.cpp

@@ -8,12 +8,19 @@
 #include <SDL_mixer.h>
 #include <SDL.h>
 
+// support for randr extended screens
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+
 #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<std::string> Screens;
+std::vector<irr::core::rect<irr::s32>> 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<void*> (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<std::string>::iterator cur = Screens.begin ();
+                std::vector<std::string>::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<irr::s32> 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<void*> (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 <folder>\tLoads an uncompressed background from the given <folder>" << std::endl
         << "  --pkg <folder>\tLoads a scene.pkg file from the given <folder>" << std::endl
-        << "  --win <WindowID>\tX Window ID to attach to" << std::endl;
+        << "  --screen-root <screen name>\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<irr::core::rect<irr::s32>>::iterator cur = Viewports.begin ();
+                std::vector<irr::core::rect<irr::s32>>::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

+ 1 - 1
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<node*>::const_iterator cur = s_nodes.begin ();
             std::vector<node*>::const_iterator end = s_nodes.end ();