From 692ba5954335ec697be734778b25ef80034742de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Sat, 4 Mar 2023 20:38:21 +0100
Subject: [PATCH 01/36] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 926625d..9d82750 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Each layer moves with Your mouse cursor, creating this beautiful effect.
[![](https://img.shields.io/github/v/release/jszczerbinsky/lwp?style=for-the-badge)](https://github.com/jszczerbinsky/lwp/releases/latest)
[![](https://img.shields.io/github/downloads/jszczerbinsky/lwp/total?style=for-the-badge)](https://github.com/jszczerbinsky/lwp/releases/latest)
[![](https://img.shields.io/github/actions/workflow/status/jszczerbinsky/lwp/build.yml?style=for-the-badge)](https://github.com/jszczerbinsky/lwp)
-[![](https://img.shields.io/discord/1077955077974794322?label=DISCORD&style=for-the-badge)](https://discord.gg/gHpbkXJD)
+[![](https://img.shields.io/discord/1077955077974794322?label=DISCORD&style=for-the-badge)](https://discord.gg/JmkCqjYFQa)
[Installation](#installation) •
[Configuration](#configuration) •
@@ -150,7 +150,7 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
## Creating Wallpapers
-Want to share Your wallpaper? Join our [discord](https://discord.gg/gHpbkXJD)!
+Want to share Your wallpaper? Join our [discord]https://discord.gg/JmkCqjYFQa)!
Parallax wallpapers are not popular. Because of this if You want some cool parallax wallpaper, You have to either find a parallax game background on the internet and use it as a wallpaper or cut some real wallpaper into layers using Gimp or Photoshop.
From 50ff76f24e7332e639715c24413d13326ace84f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Sat, 4 Mar 2023 20:38:44 +0100
Subject: [PATCH 02/36] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 9d82750..19b2333 100644
--- a/README.md
+++ b/README.md
@@ -150,7 +150,7 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
## Creating Wallpapers
-Want to share Your wallpaper? Join our [discord]https://discord.gg/JmkCqjYFQa)!
+Want to share Your wallpaper? Join our [discord](https://discord.gg/JmkCqjYFQa)!
Parallax wallpapers are not popular. Because of this if You want some cool parallax wallpaper, You have to either find a parallax game background on the internet and use it as a wallpaper or cut some real wallpaper into layers using Gimp or Photoshop.
From 8bd22c25e8ad1f6e032b81458d115a4b77a44e72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Mon, 1 May 2023 09:17:55 +0000
Subject: [PATCH 03/36] Update README.md
---
README.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 9a09cbb..364df25 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-# LWP
+# Layered WallPaper
-LWP allows You to create multi-layered parallax wallpapers.
+Layered WallPaper allows You to create multi-layered parallax wallpapers.
Each layer moves with Your mouse cursor, creating this beautiful effect.
[![](https://img.shields.io/github/v/release/jszczerbinsky/lwp?style=for-the-badge)](https://github.com/jszczerbinsky/lwp/releases/latest)
@@ -34,9 +34,9 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
```shell
sudo tar -o -xvf [archive name].tar.gz --directory /
```
- - Test lwp by running `lwp`
+ - Test Layered WallPaper by running `lwp`
- Setting `reload_rootwindow=1` in config file may be necessary on some distributions for Layered WallPaper to work properly (see [configuration](#configuration))
- - To make lwp run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
+ - To make Layered WallPaper run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
#### Build from source instead
- Install `SDL2` using Your package manager. On some distributions `SDL2` doesn't contain development files, so it may be also necessary to install development version of `SDL2`
@@ -60,9 +60,9 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
```shell
sudo tar -o -xvf [archive name].tar.gz --directory /
```
- - Test lwp by running `lwp`
+ - Test Layered WallPaper by running `lwp`
- Setting `reload_rootwindow=1` in config file may be necessary on some distributions for Layered WallPaper to work properly (see [configuration](#configuration))
- - To make lwp run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
+ - To make Layered WallPaper run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
@@ -200,7 +200,7 @@ Want to share Your wallpaper? Join our [discord](https://discord.gg/JmkCqjYFQa)!
Parallax wallpapers are not popular. Because of this if You want some cool parallax wallpaper, You have to either find a parallax game background on the internet and use it as a wallpaper or cut some real wallpaper into layers using Gimp or Photoshop.
-#### How to create a wallpaper for lwp
+#### How to create a wallpaper for Layered WallPaper
- Create a directory for Your wallpaper
- Save each layer to this directory as `.bmp` file and name them `1.bmp`, `2.bmp` ... (`1.bmp` is bottom most layer)
- Create a wallpaper config file and name it `wallpaper.cfg` (You can make a copy from `C:\Program Files\lwp\wallpapers\default-fullhd\wallpaper.cfg`)
From a859f2606728006afde5c52396ecf5f804d1683a Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sat, 30 Dec 2023 21:44:46 +0000
Subject: [PATCH 04/36] new project structure
---
.gitignore | 5 +
CMakeLists.txt | 88 ++-----
main.c | 240 ------------------
src/core/CMakeLists.txt | 51 ++++
src/core/main.c | 31 +++
src/window_templates/main.glade | 175 +++++++++++++
src/wlp/CMakeLists.txt | 77 ++++++
debug.c => src/wlp/debug.c | 0
debug.h => src/wlp/debug.h | 0
src/wlp/main.c | 95 +++++++
main.h => src/wlp/main.h | 11 +-
parser.c => src/wlp/parser.c | 4 +-
parser.h => src/wlp/parser.h | 2 +-
platform_guard.h => src/wlp/platform_guard.h | 0
.../wlp/resource.template.rc | 4 +-
src/wlp/wallpaper.c | 211 +++++++++++++++
src/wlp/wallpaper.h | 10 +
window.c => src/wlp/window.c | 37 +--
window.h => src/wlp/window.h | 2 +-
wallpaper.c | 73 ------
wallpaper.h | 9 -
21 files changed, 700 insertions(+), 425 deletions(-)
delete mode 100644 main.c
create mode 100644 src/core/CMakeLists.txt
create mode 100644 src/core/main.c
create mode 100644 src/window_templates/main.glade
create mode 100644 src/wlp/CMakeLists.txt
rename debug.c => src/wlp/debug.c (100%)
rename debug.h => src/wlp/debug.h (100%)
create mode 100644 src/wlp/main.c
rename main.h => src/wlp/main.h (95%)
rename parser.c => src/wlp/parser.c (98%)
rename parser.h => src/wlp/parser.h (79%)
rename platform_guard.h => src/wlp/platform_guard.h (100%)
rename resource.template.rc => src/wlp/resource.template.rc (91%)
create mode 100644 src/wlp/wallpaper.c
create mode 100644 src/wlp/wallpaper.h
rename window.c => src/wlp/window.c (86%)
rename window.h => src/wlp/window.h (81%)
delete mode 100644 wallpaper.c
delete mode 100644 wallpaper.h
diff --git a/.gitignore b/.gitignore
index 8ec5a32..90b3ebb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,15 @@
resource.rc
.DS_Store
+compile_commands.json
+.cache
+
data/
build/
*.res
+.vscode
+
# Prerequisites
*.d
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b839e4..2d73e6f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,19 +1,17 @@
cmake_minimum_required(VERSION 3.13)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
project(lwp
LANGUAGES C)
-if(SDL2_RUNTIME_DIR)
- string(REPLACE "\\" "/" SDL2_RUNTIME_DIR ${SDL2_RUNTIME_DIR})
-endif()
-
# Detect the platform
if (APPLE)
- set(_UNAME "DARWIN")
+ set(_UNAME "DARWIN")
elseif (WIN32)
- set(_UNAME "WIN32")
+ set(_UNAME "WIN32")
else()
- set(_UNAME "LINUX")
+ set(_UNAME "LINUX")
endif()
# Detect version
@@ -35,47 +33,6 @@ if(NOT DEFINED PROGRAM_VERSION)
message(WARNING "Can't determine Layered WallPaper version")
endif()
-set(_SOURCE_FILES
- main.c
- debug.c
- parser.c
- wallpaper.c
- window.c
- )
-
-# Windows resource file
-if(_UNAME STREQUAL "WIN32")
- if(MINGW)
- set(CMAKE_RC_COMPILER_INIT windres)
- ENABLE_LANGUAGE(RC)
- SET(CMAKE_RC_COMPILE_OBJECT
- " -O coff -i -o ")
- endif(MINGW)
-
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource.template.rc ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
- @ONLY)
- list(APPEND _SOURCE_FILES "resource.rc")
-endif()
-
-# SDL2 dependency
-find_package(SDL2 REQUIRED CONFIG)
-set(_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
-set(_LIBS ${SDL2_LIBRARIES})
-
-if (_UNAME STREQUAL "DARWIN")
- # MacOSX framework dependencies
- list(APPEND _LIBS "-framework CoreGraphics" "-framework Foundation")
-endif()
-
-if (_UNAME STREQUAL "LINUX")
- # X11 dependency
- find_package(X11 REQUIRED)
- list(APPEND _INCLUDE_DIRS ${X11_INCLUDE_DIR})
- list(APPEND _LIBS ${X11_LIBRARIES})
-endif()
-
-option(LWP_INSTALL_LAUNCHD "Launch lwp on login (MacOSX only)" OFF)
-
# Config file
set(_DEFAULT_CONFIG_FILE default.cfg)
if(_UNAME STREQUAL "WIN32")
@@ -85,32 +42,18 @@ if (_UNAME STREQUAL "DARWIN")
set(_DEFAULT_CONFIG_FILE defaultMac.cfg)
endif()
-# Main executable
-if (_UNAME STREQUAL "DARWIN")
- add_executable(lwp MACOSX_BUNDLE ${_SOURCE_FILES})
-else()
- add_executable(lwp ${_SOURCE_FILES})
-endif()
+add_subdirectory(src/wlp)
+link_directories(src/wlp)
-# Windows specific properties for executable
-if(_UNAME STREQUAL "WIN32")
- set_property(TARGET lwp PROPERTY VS_DPI_AWARE "PerMonitor")
-endif()
-
-if(MSVC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
-endif()
-
-target_compile_definitions(lwp PUBLIC __${_UNAME})
-target_include_directories(lwp PUBLIC ${_INCLUDE_DIRS})
-target_link_libraries(lwp PRIVATE ${_LIBS})
+add_subdirectory(src/core)
+link_directories(src/core)
# Installation rules
if(_UNAME STREQUAL "WIN32")
- install(TARGETS lwp
- DESTINATION .)
install(DIRECTORY wallpapers
DESTINATION .)
+ install(DIRECTORY src/window_templates
+ DESTINATION .)
install(FILES LICENSE.txt
DESTINATION .)
install(FILES ${_DEFAULT_CONFIG_FILE}
@@ -120,20 +63,20 @@ if(_UNAME STREQUAL "WIN32")
install(FILES ${SDL2_RUNTIME_DIR}/README-SDL.txt
DESTINATION .)
elseif(_UNAME STREQUAL "LINUX")
- install(TARGETS lwp
- DESTINATION usr/local/bin)
install(DIRECTORY wallpapers
DESTINATION usr/local/share/lwp)
+ install(DIRECTORY src/window_templates
+ DESTINATION usr/local/share/lwp)
install(FILES LICENSE.txt
DESTINATION usr/local/share/lwp)
install(FILES ${_DEFAULT_CONFIG_FILE}
TYPE SYSCONF
RENAME lwp.cfg)
else()
- install(TARGETS lwp
- DESTINATION Layered_WallPaper)
install(DIRECTORY wallpapers
DESTINATION Layered_WallPaper)
+ install(DIRECTORY src/window_templates
+ DESTINATION Layered_WallPaper)
install(FILES LICENSE.txt
DESTINATION Layered_WallPaper)
install(FILES ${_DEFAULT_CONFIG_FILE}
@@ -152,6 +95,7 @@ else()
endif()
+
# Installer
if (_UNAME STREQUAL "WIN32")
set(CPACK_GENERATOR NSIS)
diff --git a/main.c b/main.c
deleted file mode 100644
index def3652..0000000
--- a/main.c
+++ /dev/null
@@ -1,240 +0,0 @@
-#include "main.h"
-
-#include "debug.h"
-#include "parser.h"
-#include "platform_guard.h"
-#include "wallpaper.h"
-#include "window.h"
-
-static int lerp(int a, int b, float t)
-{
- if (t > 1) t = 1;
- return (int)((float)a + (float)t * ((float)b - (float)a));
-}
-
-static int init(App *app, Config *cfg)
-{
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0)
- {
- lwpLog(LOG_ERROR, "%s", SDL_GetError());
- return 0;
- }
-
- initWindow(app, cfg);
-
- app->renderer =
- SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- if (app->renderer == NULL)
- {
- lwpLog(LOG_ERROR, "%s", SDL_GetError());
- return 0;
- }
-
- return 1;
-}
-
-#ifdef __WIN32
-static void initCmd()
-{
- // Create console
- AllocConsole();
- AttachConsole(ATTACH_PARENT_PROCESS);
- freopen("CONOUT$", "w", stdout);
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD dwMode = 0;
- GetConsoleMode(hOut, &dwMode);
- SetConsoleMode(hOut, dwMode | 0x0004);
-
- // Remove closing button (because closing it closes the entire app)
- HWND hwnd = GetConsoleWindow();
- HMENU hMenu = GetSystemMenu(hwnd, FALSE);
- DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
-
- // Set console title
- SetConsoleTitle("Layered WallPaper");
-}
-BOOL monitorenumproc(
- HMONITOR monitor,
- HDC hdc,
- LPRECT rect,
- LPARAM param
-)
-{
-
- int px = GetSystemMetrics(SM_XVIRTUALSCREEN);
- int py = GetSystemMetrics(SM_YVIRTUALSCREEN);
-
- MONITORINFO monitorInfo;
- monitorInfo.cbSize = sizeof(MONITORINFO);
-
- GetMonitorInfo(monitor, &monitorInfo);
- lwpLog(LOG_INFO, " Monitor: position %ldx%ld, size %ldx%ld %s",
- monitorInfo.rcMonitor.left - px,
- monitorInfo.rcMonitor.top - py,
- monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
- monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
- (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY ? "primary" : ""
- );
-
- return TRUE;
-}
-static void scanMonitors()
-{
- lwpLog(LOG_INFO, "Scanning monitors...");
- EnumDisplayMonitors(NULL, NULL, &monitorenumproc, NULL);
-}
-#endif
-
-int main(int argc, char *argv[])
-{
- lwpLog(LOG_INFO, "Starting Layered WallPaper");
-
-#ifdef __WIN32
- if (argc == 2 && strcmp(argv[1], "/console") == 0) initCmd();
- initTrayIcon();
-
- scanMonitors();
-#endif
-
- App app;
- Config cfg;
-
- int canRender = 1;
-
- if (!parseConfig(&app, &cfg) || !init(&app, &cfg) || !loadMonitors(&app, &cfg)) canRender = 0;
-
- SDL_Event event;
- int quit = 0;
-
- int mx = 0;
- int my = 0;
-
- while (!quit)
- {
- if(canRender)
- {
- static int currentX = 0;
- static int currentY = 0;
-
- static int lastTicks = 0;
-
- int ticks = SDL_GetTicks();
- float dT = (ticks - lastTicks) / 1000.0f;
- lastTicks = ticks;
-
- #ifdef __WIN32
- POINT mPos;
- GetCursorPos(&mPos);
- mx = mPos.x - GetSystemMetrics(SM_XVIRTUALSCREEN);
- my = mPos.y - GetSystemMetrics(SM_YVIRTUALSCREEN);
- #else
- SDL_GetGlobalMouseState(&mx, &my);
- #endif
-
- while (SDL_PollEvent(&event))
- if (event.type == SDL_QUIT) quit = 1;
-
- currentX = lerp(currentX, mx, dT * cfg.smooth);
- currentY = lerp(currentY, my, dT * cfg.smooth);
-
- for (int m = 0; m < cfg.monitorsCount; m++)
- {
- int relativeCurrentX = currentX - cfg.monitors[m].x;
- int relativeCurrentY = currentY - cfg.monitors[m].y;
-
- if (relativeCurrentX < 0) relativeCurrentX = 0;
- if (relativeCurrentY < 0) relativeCurrentY = 0;
- if (relativeCurrentX > cfg.monitors[m].w) relativeCurrentX = cfg.monitors[m].w;
- if (relativeCurrentY > cfg.monitors[m].h) relativeCurrentY = cfg.monitors[m].h;
-
- SDL_SetRenderTarget(app.renderer, cfg.monitors[m].wallpaper.tex);
- SDL_RenderClear(app.renderer);
-
- for (int i = 0; i < cfg.monitors[m].wallpaper.layersCount; i++)
- {
- SDL_Rect src = {
- .x = 0,
- .y = 0,
- .w = cfg.monitors[m].wallpaper.originalW,
- .h = cfg.monitors[m].wallpaper.originalH,
- };
-
- int x = -((relativeCurrentX - cfg.monitors[m].w / 2) *
- cfg.monitors[m].wallpaper.layers[i].sensitivityX);
- int y = -((relativeCurrentY - cfg.monitors[m].h / 2) *
- cfg.monitors[m].wallpaper.layers[i].sensitivityY);
-
- for (int k = -cfg.monitors[m].wallpaper.repeatY; k <= cfg.monitors[m].wallpaper.repeatY;
- k++)
- {
- for (int j = -cfg.monitors[m].wallpaper.repeatX; j <= cfg.monitors[m].wallpaper.repeatX;
- j++)
- {
- SDL_Rect dest = {
- .x = x + j * cfg.monitors[m].wallpaperW,
- .y = y + k * cfg.monitors[m].wallpaperH,
- .w = cfg.monitors[m].wallpaperW,
- .h = cfg.monitors[m].wallpaperH,
- };
-
- SDL_RenderCopy(app.renderer, cfg.monitors[m].wallpaper.layers[i].tex, &src, &dest);
- }
- }
- }
-
- SDL_SetRenderTarget(app.renderer, cfg.monitors[m].tex);
-
- SDL_Rect src = {
- .x = 0,
- .y = 0,
- .w = cfg.monitors[m].wallpaperW,
- .h = cfg.monitors[m].wallpaperH,
- };
-
- SDL_Rect dest = {
- .x = cfg.monitors[m].wallpaperX,
- .y = cfg.monitors[m].wallpaperY,
- .w = cfg.monitors[m].wallpaperW,
- .h = cfg.monitors[m].wallpaperH,
- };
-
- SDL_RenderCopy(app.renderer, cfg.monitors[m].wallpaper.tex, &src, &dest);
-
- SDL_SetRenderTarget(app.renderer, NULL);
-
- SDL_Rect finalSrc = {
- .x = 0,
- .y = 0,
- .w = cfg.monitors[m].w,
- .h = cfg.monitors[m].h,
- };
-
- SDL_Rect finalDest = {
- .x = cfg.monitors[m].x,
- .y = cfg.monitors[m].y,
- .w = cfg.monitors[m].w,
- .h = cfg.monitors[m].h,
- };
-
- SDL_RenderCopy(app.renderer, cfg.monitors[m].tex, &finalSrc, &finalDest);
- }
- SDL_RenderPresent(app.renderer);
- }
- SDL_Delay(1000 / cfg.targetFPS);
-#ifdef __WIN32
- if(!updateTrayIcon()) quit = 1;
-#endif
- }
-
-#ifdef __WIN32
- removeTrayIcon();
-#endif
-
- freeConfig(&cfg);
-
- SDL_DestroyRenderer(app.renderer);
- SDL_DestroyWindow(app.window);
- SDL_Quit();
-
- return 0;
-}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
new file mode 100644
index 0000000..f59c767
--- /dev/null
+++ b/src/core/CMakeLists.txt
@@ -0,0 +1,51 @@
+set(_SOURCE_FILES
+ main.c
+ )
+
+# Windows resource file
+if(_UNAME STREQUAL "WIN32")
+ if(MINGW)
+ set(CMAKE_RC_COMPILER_INIT windres)
+ ENABLE_LANGUAGE(RC)
+ SET(CMAKE_RC_COMPILE_OBJECT
+ " -O coff -i -o ")
+ endif(MINGW)
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource.template.rc ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
+ @ONLY)
+ list(APPEND _SOURCE_FILES "resource.rc")
+endif()
+
+# GTK dependency
+find_package (PkgConfig REQUIRED)
+pkg_check_modules (GTK3 REQUIRED gtk+-3.0)
+list(APPEND _INCLUDE_DIRS ${GTK3_INCLUDE_DIRS})
+list(APPEND _LIBS ${GTK3_LINK_LIBRARIES})
+
+# Main executable
+if (_UNAME STREQUAL "DARWIN")
+ add_executable(lwp MACOSX_BUNDLE ${_SOURCE_FILES})
+else()
+ add_executable(lwp ${_SOURCE_FILES})
+endif()
+
+if(MSVC)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
+endif()
+
+target_compile_definitions(lwp PUBLIC __${_UNAME})
+target_include_directories(lwp PUBLIC ${_INCLUDE_DIRS})
+target_link_libraries(lwp PRIVATE ${_LIBS})
+
+# Installation rules
+if(_UNAME STREQUAL "WIN32")
+ install(TARGETS lwp
+ DESTINATION .)
+elseif(_UNAME STREQUAL "LINUX")
+ install(TARGETS lwp
+ DESTINATION usr/local/bin)
+else()
+ install(TARGETS lwp
+ DESTINATION Layered_WallPaper)
+endif()
+
diff --git a/src/core/main.c b/src/core/main.c
new file mode 100644
index 0000000..d1bce05
--- /dev/null
+++ b/src/core/main.c
@@ -0,0 +1,31 @@
+#include
+
+#ifdef __WIN32
+ #define MAIN_WINDOW_TEMPLATE_PATH ""
+#elif __DARWIN
+ #define MAIN_WINDOW_TEMPLATE_PATH ""
+#else
+ #define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
+#endif
+
+static void activate(GtkApplication *app, gpointer userdata)
+{
+ GtkBuilder *builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+ GtkWidget *window = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
+ if (window == NULL) printf("wnd not found\n");
+ gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
+ gtk_widget_set_visible(window, 1);
+}
+
+int main(int argc, char *argv[])
+{
+ GtkApplication *app;
+ int status;
+
+ app = gtk_application_new ("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
+ g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
+ status = g_application_run (G_APPLICATION (app), argc, argv);
+ g_object_unref (app);
+
+ return status;
+}
\ No newline at end of file
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
new file mode 100644
index 0000000..bd863eb
--- /dev/null
+++ b/src/window_templates/main.glade
@@ -0,0 +1,175 @@
+
+
+
+
+
+ False
+ False
+ 800
+ 600
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+
+
+ Github page
+ True
+ True
+ True
+ none
+ https://github.com/jszczerbinsky/lwp
+
+
+ False
+ True
+ end
+ 0
+
+
+
+
+ True
+ False
+ 11
+ v 1.0.0
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 10
+ 10
+ Layered WallPaper
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Enhance your desktop experiance
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 120
+ 120
+ 50
+ vertical
+
+
+ True
+ False
+ 5
+ 5
+ Setup your screens
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ True
+ True
+
+
+ True
+ False
+ start
+ 10
+ 10
+ Monitor 2
+
+
+
+
+
+
+ True
+ True
+
+
+ True
+ False
+ start
+ 10
+ 10
+ Monitor 1
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ 2
+
+
+
+
+
+
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
new file mode 100644
index 0000000..64e71d8
--- /dev/null
+++ b/src/wlp/CMakeLists.txt
@@ -0,0 +1,77 @@
+if(SDL2_RUNTIME_DIR)
+ string(REPLACE "\\" "/" SDL2_RUNTIME_DIR ${SDL2_RUNTIME_DIR})
+endif()
+
+set(_SOURCE_FILES
+ main.c
+ debug.c
+ parser.c
+ wallpaper.c
+ window.c
+ )
+
+# Windows resource file
+if(_UNAME STREQUAL "WIN32")
+ if(MINGW)
+ set(CMAKE_RC_COMPILER_INIT windres)
+ ENABLE_LANGUAGE(RC)
+ SET(CMAKE_RC_COMPILE_OBJECT
+ " -O coff -i -o ")
+ endif(MINGW)
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource.template.rc ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
+ @ONLY)
+ list(APPEND _SOURCE_FILES "resource.rc")
+endif()
+
+# SDL2 dependency
+find_package(SDL2 REQUIRED CONFIG)
+set(_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
+set(_LIBS ${SDL2_LIBRARIES})
+
+if (_UNAME STREQUAL "DARWIN")
+ # MacOSX framework dependencies
+ list(APPEND _LIBS "-framework CoreGraphics" "-framework Foundation")
+endif()
+
+if (_UNAME STREQUAL "LINUX")
+ # X11 dependency
+ find_package(X11 REQUIRED)
+ list(APPEND _INCLUDE_DIRS ${X11_INCLUDE_DIR})
+ list(APPEND _LIBS ${X11_LIBRARIES})
+endif()
+
+option(LWP_INSTALL_LAUNCHD "Launch lwp on login (MacOSX only)" OFF)
+
+# Main executable
+if (_UNAME STREQUAL "DARWIN")
+ add_executable(lwpwlp MACOSX_BUNDLE ${_SOURCE_FILES})
+else()
+ add_executable(lwpwlp ${_SOURCE_FILES})
+endif()
+
+# Windows specific properties for executable
+if(_UNAME STREQUAL "WIN32")
+ set_property(TARGET lwpwlp PROPERTY VS_DPI_AWARE "PerMonitor")
+endif()
+
+if(MSVC)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
+endif()
+
+target_compile_definitions(lwpwlp PUBLIC __${_UNAME})
+target_include_directories(lwpwlp PUBLIC ${_INCLUDE_DIRS})
+target_link_libraries(lwpwlp PRIVATE ${_LIBS})
+
+# Installation rules
+if(_UNAME STREQUAL "WIN32")
+ install(TARGETS lwpwlp
+ DESTINATION .)
+elseif(_UNAME STREQUAL "LINUX")
+ install(TARGETS lwpwlp
+ DESTINATION usr/local/bin)
+else()
+ install(TARGETS lwpwlp
+ DESTINATION Layered_WallPaper)
+endif()
+
diff --git a/debug.c b/src/wlp/debug.c
similarity index 100%
rename from debug.c
rename to src/wlp/debug.c
diff --git a/debug.h b/src/wlp/debug.h
similarity index 100%
rename from debug.h
rename to src/wlp/debug.h
diff --git a/src/wlp/main.c b/src/wlp/main.c
new file mode 100644
index 0000000..5c66e9a
--- /dev/null
+++ b/src/wlp/main.c
@@ -0,0 +1,95 @@
+#include "main.h"
+
+#include "debug.h"
+#include "parser.h"
+#include "platform_guard.h"
+#include "wallpaper.h"
+#include "window.h"
+
+#ifdef __WIN32
+static void initCmd()
+{
+ // Create console
+ AllocConsole();
+ AttachConsole(ATTACH_PARENT_PROCESS);
+ freopen("CONOUT$", "w", stdout);
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD dwMode = 0;
+ GetConsoleMode(hOut, &dwMode);
+ SetConsoleMode(hOut, dwMode | 0x0004);
+
+ // Remove closing button (because closing it closes the entire app)
+ HWND hwnd = GetConsoleWindow();
+ HMENU hMenu = GetSystemMenu(hwnd, FALSE);
+ DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
+
+ // Set console title
+ SetConsoleTitle("Layered WallPaper");
+}
+BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
+{
+ int px = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ int py = GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ MONITORINFO monitorInfo;
+ monitorInfo.cbSize = sizeof(MONITORINFO);
+
+ GetMonitorInfo(monitor, &monitorInfo);
+ lwpLog(
+ LOG_INFO,
+ " Monitor: position %ldx%ld, size %ldx%ld %s",
+ monitorInfo.rcMonitor.left - px,
+ monitorInfo.rcMonitor.top - py,
+ monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
+ monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
+ (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY ? "primary" : ""
+ );
+
+ return TRUE;
+}
+static void scanMonitors()
+{
+ lwpLog(LOG_INFO, "Scanning monitors...");
+ EnumDisplayMonitors(NULL, NULL, &monitorenumproc, NULL);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ lwpLog(LOG_INFO, "Starting Layered WallPaper");
+
+#ifdef __WIN32
+ if (argc == 2 && strcmp(argv[1], "/console") == 0) initCmd();
+ initTrayIcon();
+
+ scanMonitors();
+#endif
+
+ Config cfg;
+ parseConfig(&cfg);
+
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
+ initWindow(&cfg);
+
+ cfg.renderer =
+ SDL_CreateRenderer(cfg.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (cfg.renderer == NULL)
+ {
+ lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ }
+
+ runWallpaperLoop(&cfg);
+
+
+#ifdef __WIN32
+ removeTrayIcon();
+#endif
+
+ freeConfig(&cfg);
+
+ SDL_DestroyRenderer(cfg.renderer);
+ SDL_DestroyWindow(cfg.window);
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/main.h b/src/wlp/main.h
similarity index 95%
rename from main.h
rename to src/wlp/main.h
index 55d0e08..f30a5b3 100644
--- a/main.h
+++ b/src/wlp/main.h
@@ -49,20 +49,17 @@ typedef struct
int wallpaperX, wallpaperY, wallpaperW, wallpaperH;
SDL_Texture *tex;
Wallpaper wallpaper;
-} Monitor;
+} WallpaperDest;
+
typedef struct
{
int reloadRootWnd;
int monitorsCount;
float smooth;
int targetFPS;
- Monitor *monitors;
-} Config;
-
-typedef struct
-{
+ WallpaperDest *monitors;
SDL_Window *window;
SDL_Renderer *renderer;
-} App;
+} Config;
#endif // MAIN_H
diff --git a/parser.c b/src/wlp/parser.c
similarity index 98%
rename from parser.c
rename to src/wlp/parser.c
index 85b0c76..26a407c 100644
--- a/parser.c
+++ b/src/wlp/parser.c
@@ -146,7 +146,7 @@ static int findLine(FILE *f, const char *name, int type, void *output)
return found;
}
-int parseConfig(App *app, Config *cfg)
+int parseConfig(Config *cfg)
{
lwpLog(LOG_INFO, "Loading config file");
@@ -182,7 +182,7 @@ int parseConfig(App *app, Config *cfg)
lwpLog(LOG_INFO, " reload_rootwindow: %d", cfg->reloadRootWnd);
#endif
- cfg->monitors = malloc(cfg->monitorsCount * sizeof(Monitor));
+ cfg->monitors = malloc(cfg->monitorsCount * sizeof(WallpaperDest));
for (int m = 0; m < cfg->monitorsCount; m++)
{
diff --git a/parser.h b/src/wlp/parser.h
similarity index 79%
rename from parser.h
rename to src/wlp/parser.h
index 55fa65a..d20603c 100644
--- a/parser.h
+++ b/src/wlp/parser.h
@@ -3,7 +3,7 @@
#include "main.h"
-int parseConfig(App *app, Config *cfg);
+int parseConfig(Config *cfg);
int parseWallpaperConfig(Wallpaper *wallpaper, const char *path);
void freeConfig(Config *cfg);
diff --git a/platform_guard.h b/src/wlp/platform_guard.h
similarity index 100%
rename from platform_guard.h
rename to src/wlp/platform_guard.h
diff --git a/resource.template.rc b/src/wlp/resource.template.rc
similarity index 91%
rename from resource.template.rc
rename to src/wlp/resource.template.rc
index 892e717..16de8c9 100644
--- a/resource.template.rc
+++ b/src/wlp/resource.template.rc
@@ -3,7 +3,7 @@
#define PROGRAM_VER "@PROGRAM_VERSION@"
-id ICON "icon.ico"
+id ICON "..\..\icon.ico"
VS_VERSION_INFO VERSIONINFO
FILEOS VOS_NT
@@ -19,7 +19,7 @@ BEGIN
VALUE "FileVersion", PROGRAM_VER
VALUE "InternalName", "Layered WallPaper"
VALUE "LegalCopyright", "(c) 2022 Jakub Szczerbiński"
- VALUE "OriginalFilename", "lwp.exe"
+ VALUE "OriginalFilename", "lwpwlp.exe"
VALUE "ProductName", "Layered WallPaper"
VALUE "ProductVersion", PROGRAM_VER
END
diff --git a/src/wlp/wallpaper.c b/src/wlp/wallpaper.c
new file mode 100644
index 0000000..edec74a
--- /dev/null
+++ b/src/wlp/wallpaper.c
@@ -0,0 +1,211 @@
+#ifdef _MSC_VER
+#include
+#else
+#include
+#endif
+
+#include "debug.h"
+#include "parser.h"
+
+static int appplyWallpaper(Config *cfg, WallpaperDest *monitor, Wallpaper *wallpaper, const char *dirPath)
+{
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/wallpaper.cfg", dirPath);
+
+ if (!parseWallpaperConfig(wallpaper, path))
+ {
+ return 0;
+ }
+
+ for (int i = 0; i < wallpaper->layersCount; i++)
+ {
+ snprintf(path, PATH_MAX, "%s/%d.bmp", dirPath, i + 1);
+
+ SDL_Surface *surf = SDL_LoadBMP(path);
+ if (!surf)
+ {
+ lwpLog(LOG_ERROR, "File %s not found", path);
+ return 0;
+ }
+
+ if (i == 0)
+ {
+ wallpaper->originalW = surf->w;
+ wallpaper->originalH = surf->h;
+ }
+
+ wallpaper->layers[i].tex = SDL_CreateTextureFromSurface(cfg->renderer, surf);
+
+ SDL_FreeSurface(surf);
+ }
+
+ wallpaper->tex =
+ SDL_CreateTexture(cfg->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
+ monitor->wallpaperW, monitor->wallpaperH);
+
+ monitor->tex = SDL_CreateTexture(cfg->renderer, SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET, monitor->w, monitor->h);
+
+ return 1;
+}
+
+int applyWallpapers(Config *cfg)
+{
+ for (int m = 0; m < cfg->monitorsCount; m++)
+ if (!appplyWallpaper(cfg, &cfg->monitors[m], &cfg->monitors[m].wallpaper,
+ cfg->monitors[m].wallpaper.dirPath))
+ return 0;
+
+ return 1;
+}
+
+void freeMonitor(WallpaperDest *monitor)
+{
+ SDL_DestroyTexture(monitor->tex);
+ SDL_DestroyTexture(monitor->wallpaper.tex);
+
+ for (int i = 0; i < monitor->wallpaper.layersCount; i++)
+ {
+ SDL_DestroyTexture(monitor->wallpaper.layers[i].tex);
+ }
+ free(monitor->wallpaper.layers);
+}
+
+static int lerp(int a, int b, float t)
+{
+ if (t > 1) t = 1;
+ return (int)((float)a + (float)t * ((float)b - (float)a));
+}
+
+void runWallpaperLoop(Config *cfg)
+{
+ int quit = 0;
+
+ if(!applyWallpapers(cfg))
+ {
+ lwpLog(LOG_ERROR, "Failed applying wallpapers");
+ quit = 1;
+ }
+
+ SDL_Event event;
+
+ int mx = 0;
+ int my = 0;
+
+ while (!quit)
+ {
+ static int currentX = 0;
+ static int currentY = 0;
+
+ static int lastTicks = 0;
+
+ int ticks = SDL_GetTicks();
+ float dT = (ticks - lastTicks) / 1000.0f;
+ lastTicks = ticks;
+
+#ifdef __WIN32
+ POINT mPos;
+ GetCursorPos(&mPos);
+ mx = mPos.x - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ my = mPos.y - GetSystemMetrics(SM_YVIRTUALSCREEN);
+#else
+ SDL_GetGlobalMouseState(&mx, &my);
+#endif
+
+ while (SDL_PollEvent(&event))
+ if (event.type == SDL_QUIT) quit = 1;
+
+ currentX = lerp(currentX, mx, dT * cfg->smooth);
+ currentY = lerp(currentY, my, dT * cfg->smooth);
+
+ for (int m = 0; m < cfg->monitorsCount; m++)
+ {
+ int relativeCurrentX = currentX - cfg->monitors[m].x;
+ int relativeCurrentY = currentY - cfg->monitors[m].y;
+
+ if (relativeCurrentX < 0) relativeCurrentX = 0;
+ if (relativeCurrentY < 0) relativeCurrentY = 0;
+ if (relativeCurrentX > cfg->monitors[m].w) relativeCurrentX = cfg->monitors[m].w;
+ if (relativeCurrentY > cfg->monitors[m].h) relativeCurrentY = cfg->monitors[m].h;
+
+ SDL_SetRenderTarget(cfg->renderer, cfg->monitors[m].wallpaper.tex);
+ SDL_RenderClear(cfg->renderer);
+
+ for (int i = 0; i < cfg->monitors[m].wallpaper.layersCount; i++)
+ {
+ SDL_Rect src = {
+ .x = 0,
+ .y = 0,
+ .w = cfg->monitors[m].wallpaper.originalW,
+ .h = cfg->monitors[m].wallpaper.originalH,
+ };
+
+ int x =
+ -((relativeCurrentX - cfg->monitors[m].w / 2) *
+ cfg->monitors[m].wallpaper.layers[i].sensitivityX);
+ int y =
+ -((relativeCurrentY - cfg->monitors[m].h / 2) *
+ cfg->monitors[m].wallpaper.layers[i].sensitivityY);
+
+ for (int k = -cfg->monitors[m].wallpaper.repeatY; k <= cfg->monitors[m].wallpaper.repeatY;
+ k++)
+ {
+ for (int j = -cfg->monitors[m].wallpaper.repeatX; j <= cfg->monitors[m].wallpaper.repeatX;
+ j++)
+ {
+ SDL_Rect dest = {
+ .x = x + j * cfg->monitors[m].wallpaperW,
+ .y = y + k * cfg->monitors[m].wallpaperH,
+ .w = cfg->monitors[m].wallpaperW,
+ .h = cfg->monitors[m].wallpaperH,
+ };
+
+ SDL_RenderCopy(cfg->renderer, cfg->monitors[m].wallpaper.layers[i].tex, &src, &dest);
+ }
+ }
+ }
+
+ SDL_SetRenderTarget(cfg->renderer, cfg->monitors[m].tex);
+
+ SDL_Rect src = {
+ .x = 0,
+ .y = 0,
+ .w = cfg->monitors[m].wallpaperW,
+ .h = cfg->monitors[m].wallpaperH,
+ };
+
+ SDL_Rect dest = {
+ .x = cfg->monitors[m].wallpaperX,
+ .y = cfg->monitors[m].wallpaperY,
+ .w = cfg->monitors[m].wallpaperW,
+ .h = cfg->monitors[m].wallpaperH,
+ };
+
+ SDL_RenderCopy(cfg->renderer, cfg->monitors[m].wallpaper.tex, &src, &dest);
+
+ SDL_SetRenderTarget(cfg->renderer, NULL);
+
+ SDL_Rect finalSrc = {
+ .x = 0,
+ .y = 0,
+ .w = cfg->monitors[m].w,
+ .h = cfg->monitors[m].h,
+ };
+
+ SDL_Rect finalDest = {
+ .x = cfg->monitors[m].x,
+ .y = cfg->monitors[m].y,
+ .w = cfg->monitors[m].w,
+ .h = cfg->monitors[m].h,
+ };
+
+ SDL_RenderCopy(cfg->renderer, cfg->monitors[m].tex, &finalSrc, &finalDest);
+ }
+ SDL_RenderPresent(cfg->renderer);
+ SDL_Delay(1000 / cfg->targetFPS);
+#ifdef __WIN32
+ if (!updateTrayIcon()) quit = 1;
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/wlp/wallpaper.h b/src/wlp/wallpaper.h
new file mode 100644
index 0000000..92b1631
--- /dev/null
+++ b/src/wlp/wallpaper.h
@@ -0,0 +1,10 @@
+#ifndef WALLPAPER_H
+#define WALLPAPER_H
+
+#include "main.h"
+
+int applyWallpapers(Config *cfg);
+void freeMonitor(WallpaperDest *monitor);
+void runWallpaperLoop(Config *cfg);
+
+#endif
diff --git a/window.c b/src/wlp/window.c
similarity index 86%
rename from window.c
rename to src/wlp/window.c
index 90aa3dd..68b6228 100644
--- a/window.c
+++ b/src/wlp/window.c
@@ -104,7 +104,7 @@ void initTrayIcon()
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(0, CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ HWND hWnd = CreateWindowEx(0, CLASS_NAME, L"", WS_OVERLcfgEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
// Create tray icon
@@ -118,15 +118,15 @@ void initTrayIcon()
Shell_NotifyIcon(NIM_ADD, &nid);
}
-void initWindow(App *app, Config *cfg)
+void initWindow(Config *cfg)
{
- app->window =
+ cfg->window =
SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
- if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
SDL_SysWMinfo sysWmInfo;
SDL_VERSION(&sysWmInfo.version)
- SDL_GetWindowWMInfo(app->window, &sysWmInfo);
+ SDL_GetWindowWMInfo(cfg->window, &sysWmInfo);
HWND hWindow = sysWmInfo.info.win.window;
HWND progman = FindWindow("Progman", NULL);
@@ -155,7 +155,7 @@ void initWindow(App *app, Config *cfg)
#define OBJC_MSG_CLS ((id(*)(Class, SEL))objc_msgSend)
#define OBJC_MSG_CLS_CHR ((id(*)(Class, SEL, char *))objc_msgSend)
-void initWindow(App *app, Config *cfg)
+void initWindow(Config *cfg)
{
// Get main display size
const CGDirectDisplayID displayID = CGMainDisplayID();
@@ -163,10 +163,10 @@ void initWindow(App *app, Config *cfg)
const size_t h = CGDisplayPixelsHigh(displayID);
const struct CGRect frameRect = {0, 0, w, h};
- // Get shared NSApplication instance
- const id ns_app = OBJC_MSG_CLS(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
- OBJC_MSG_INT(ns_app, sel_getUid("setActivationPolicy:"),
- 0); // NSApplicationActivationPolicyRegular
+ // Get shared NScfglication instance
+ const id ns_cfg = OBJC_MSG_CLS(objc_getClass("NScfglication"), sel_getUid("sharedcfglication"));
+ OBJC_MSG_INT(ns_cfg, sel_getUid("setActivationPolicy:"),
+ 0); // NScfglicationActivationPolicyRegular
// Create NSWindow
const id window = ((id(*)(id, SEL, struct CGRect, int, int, int))objc_msgSend)(
@@ -182,28 +182,28 @@ void initWindow(App *app, Config *cfg)
"Parallax wallpaper"));
OBJC_MSG_PTR(window, sel_getUid("makeKeyAndOrderFront:"), nil);
OBJC_MSG_INT(window, sel_getUid("setLevel:"), kCGDesktopWindowLevel - 1);
- OBJC_MSG_INT(ns_app, sel_getUid("activateIgnoringOtherApps:"), true);
+ OBJC_MSG_INT(ns_cfg, sel_getUid("activateIgnoringOthercfgs:"), true);
// Create SDL window from NSWindow
- app->window = SDL_CreateWindowFrom((void *)window);
- if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ cfg->window = SDL_CreateWindowFrom((void *)window);
+ if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
}
#elif __LINUX
-void initWindow(App *app, Config *cfg)
+void initWindow(Config *cfg)
{
if (cfg->reloadRootWnd)
{
Display *display = XOpenDisplay(NULL);
XCloseDisplay(display);
- app->window = SDL_CreateWindow("Parallax wallpaper", 0, 0, DisplayWidth(display, 0),
+ cfg->window = SDL_CreateWindow("Parallax wallpaper", 0, 0, DisplayWidth(display, 0),
DisplayHeight(display, 0), SDL_WINDOW_OPENGL);
SDL_SysWMinfo wmInfo;
SDL_GetVersion(&wmInfo.version);
- SDL_GetWindowWMInfo(app->window, &wmInfo);
+ SDL_GetWindowWMInfo(cfg->window, &wmInfo);
Window xWnd = wmInfo.info.x11.window;
display = wmInfo.info.x11.display;
@@ -223,10 +223,11 @@ void initWindow(App *app, Config *cfg)
{
Display *display = XOpenDisplay(NULL);
Window rootWindow = RootWindow(display, DefaultScreen(display));
- app->window = SDL_CreateWindowFrom((void *)rootWindow);
+ cfg->window = SDL_CreateWindowFrom((void *)rootWindow);
XCloseDisplay(display);
}
- if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+
}
#endif
diff --git a/window.h b/src/wlp/window.h
similarity index 81%
rename from window.h
rename to src/wlp/window.h
index b69063f..fc4a498 100644
--- a/window.h
+++ b/src/wlp/window.h
@@ -4,7 +4,7 @@
#include "main.h"
#include "parser.h"
-void initWindow(App *app, Config *cfg);
+void initWindow(Config *cfg);
#ifdef __WIN32
void initTrayIcon();
diff --git a/wallpaper.c b/wallpaper.c
deleted file mode 100644
index a57d906..0000000
--- a/wallpaper.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifdef _MSC_VER
-#include
-#else
-#include
-#endif
-
-#include "debug.h"
-#include "parser.h"
-
-static int loadMonitor(App *app, Monitor *monitor, Wallpaper *wallpaper, const char *dirPath)
-{
- char path[PATH_MAX];
-
- snprintf(path, PATH_MAX, "%s/wallpaper.cfg", dirPath);
-
- if (!parseWallpaperConfig(wallpaper, path))
- {
- return 0;
- }
-
- for (int i = 0; i < wallpaper->layersCount; i++)
- {
- snprintf(path, PATH_MAX, "%s/%d.bmp", dirPath, i + 1);
-
- SDL_Surface *surf = SDL_LoadBMP(path);
- if (!surf)
- {
- lwpLog(LOG_ERROR, "File %s not found", path);
- return 0;
- }
-
- if (i == 0)
- {
- wallpaper->originalW = surf->w;
- wallpaper->originalH = surf->h;
- }
-
- wallpaper->layers[i].tex = SDL_CreateTextureFromSurface(app->renderer, surf);
-
- SDL_FreeSurface(surf);
- }
-
- wallpaper->tex =
- SDL_CreateTexture(app->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
- monitor->wallpaperW, monitor->wallpaperH);
-
- monitor->tex = SDL_CreateTexture(app->renderer, SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_TARGET, monitor->w, monitor->h);
-
- return 1;
-}
-
-int loadMonitors(App *app, Config *cfg)
-{
- for (int m = 0; m < cfg->monitorsCount; m++)
- if (!loadMonitor(app, &cfg->monitors[m], &cfg->monitors[m].wallpaper,
- cfg->monitors[m].wallpaper.dirPath))
- return 0;
-
- return 1;
-}
-
-void freeMonitor(Monitor *monitor)
-{
- SDL_DestroyTexture(monitor->tex);
- SDL_DestroyTexture(monitor->wallpaper.tex);
-
- for (int i = 0; i < monitor->wallpaper.layersCount; i++)
- {
- SDL_DestroyTexture(monitor->wallpaper.layers[i].tex);
- }
- free(monitor->wallpaper.layers);
-}
diff --git a/wallpaper.h b/wallpaper.h
deleted file mode 100644
index 11da0eb..0000000
--- a/wallpaper.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef WALLPAPER_H
-#define WALLPAPER_H
-
-#include "main.h"
-
-int loadMonitors(App *app, Config *cfg);
-void freeMonitor(Monitor *monitor);
-
-#endif
From 814ad6cc8df65faf9d72f5d34ba20cdb0e1473d7 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sun, 31 Dec 2023 17:23:46 +0000
Subject: [PATCH 05/36] Wallpaper subprocess
---
src/core/main.c | 53 ++++++++++--
src/window_templates/main.glade | 137 ++++++++++++++++++++++++++------
src/wlp/main.c | 39 ++++++---
src/wlp/main.h | 2 +
4 files changed, 189 insertions(+), 42 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index d1bce05..bd6cf22 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -8,13 +8,56 @@
#define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
#endif
+GtkBuilder *builder = NULL;
+static FILE *wlpProcess = NULL;
+int wlpPid = 0;
+
+static void killWlp()
+{
+ if(wlpPid != 0)
+ kill(wlpPid, SIGINT);
+ if(wlpProcess != NULL)
+ pclose(wlpProcess);
+
+ wlpPid = 0;
+ wlpProcess = NULL;
+}
+
+static void runWlp()
+{
+ wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
+ char buff[10];
+ fgets(buff, sizeof(buff) - 1, wlpProcess);
+ wlpPid = atoi(buff);
+}
+
+static gboolean exitClicked(GtkWidget *btn, GdkEvent *event, gpointer userdata)
+{
+ killWlp();
+ g_application_quit(G_APPLICATION(userdata));
+}
+
+static gboolean deleted(GtkWidget *window, GdkEvent *event, gpointer userdata)
+{
+ gtk_widget_hide(window);
+}
+
static void activate(GtkApplication *app, gpointer userdata)
{
- GtkBuilder *builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
- GtkWidget *window = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
- if (window == NULL) printf("wnd not found\n");
- gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
- gtk_widget_set_visible(window, 1);
+ builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+ GtkWidget *window = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
+ if (window == NULL) printf("wnd not found\n");
+
+ g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(deleted), NULL);
+
+ GtkWidget *exitBtn = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ExitBtn");
+
+ g_signal_connect(G_OBJECT(exitBtn), "clicked", G_CALLBACK(exitClicked), app);
+
+ gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
+ gtk_widget_set_visible(window, 1);
+
+ runWlp();
}
int main(int argc, char *argv[])
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index bd863eb..173c979 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -2,6 +2,66 @@
+
+ False
+ dialog
+
+
+ False
+ vertical
+ 2
+
+
+ False
+ end
+
+
+ Yes
+ True
+ True
+ True
+
+
+ True
+ True
+ 0
+
+
+
+
+ No
+ True
+ True
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ Are you sure, you want to exit Layered WallPaper?
+
+
+ False
+ True
+ 1
+
+
+
+
+
False
False
@@ -17,32 +77,32 @@
True
False
-
- Github page
+
True
- True
- True
- none
- https://github.com/jszczerbinsky/lwp
+ False
+ 11
+ v 1.0.0
False
True
- end
- 0
+ 1
-
+
+ Github page
True
- False
- 11
- v 1.0.0
+ True
+ True
+ none
+ https://github.com/jszczerbinsky/lwp
False
True
- 1
+ end
+ 2
@@ -57,33 +117,60 @@
True
False
- vertical
-
+
True
False
- 10
- 10
- Layered WallPaper
-
-
-
+ vertical
+
+
+ True
+ False
+ 10
+ 10
+ Layered WallPaper
+ center
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Enhance your desktop experiance
+ center
+
+
+ False
+ True
+ 1
+
+
- False
+ True
True
0
-
+
+ Exit
True
- False
- Enhance your desktop experiance
+ True
+ True
False
True
+ end
1
diff --git a/src/wlp/main.c b/src/wlp/main.c
index 5c66e9a..0f68eb6 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -54,8 +54,30 @@ static void scanMonitors()
}
#endif
+static Config cfg;
+
+static void atExit()
+{
+ freeConfig(&cfg);
+
+ SDL_DestroyRenderer(cfg.renderer);
+ SDL_DestroyWindow(cfg.window);
+ SDL_Quit();
+}
+
+void exitSignalHandler(int s)
+{
+ exit(0);
+}
+
int main(int argc, char *argv[])
{
+ char pidStr[10];
+ sprintf(pidStr, "%d\0", getpid());
+ fputs(pidStr, stdout);
+
+ signal(SIGINT, exitSignalHandler);
+
lwpLog(LOG_INFO, "Starting Layered WallPaper");
#ifdef __WIN32
@@ -65,31 +87,24 @@ int main(int argc, char *argv[])
scanMonitors();
#endif
- Config cfg;
parseConfig(&cfg);
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
initWindow(&cfg);
+ atexit(atExit);
+
cfg.renderer =
SDL_CreateRenderer(cfg.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (cfg.renderer == NULL)
{
lwpLog(LOG_ERROR, "%s", SDL_GetError());
}
-
runWallpaperLoop(&cfg);
-
-#ifdef __WIN32
- removeTrayIcon();
-#endif
-
- freeConfig(&cfg);
-
- SDL_DestroyRenderer(cfg.renderer);
- SDL_DestroyWindow(cfg.window);
- SDL_Quit();
+ #ifdef __WIN32
+ removeTrayIcon();
+ #endif
return 0;
}
diff --git a/src/wlp/main.h b/src/wlp/main.h
index f30a5b3..09de760 100644
--- a/src/wlp/main.h
+++ b/src/wlp/main.h
@@ -18,12 +18,14 @@
#include
#include
#include
+#include
#elif __LINUX
#include
#include
#include
#include
#include
+#include
#endif
typedef struct
From cc55b03045333775f873c91626a7df4fbbda76d6 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sun, 31 Dec 2023 17:46:24 +0000
Subject: [PATCH 06/36] Exit dialog
---
src/core/main.c | 31 +++++++++++++++++++++++++------
src/window_templates/main.glade | 4 ++--
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index bd6cf22..d62e5af 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -9,6 +9,7 @@
#endif
GtkBuilder *builder = NULL;
+GtkWidget *exitDialog = NULL;
static FILE *wlpProcess = NULL;
int wlpPid = 0;
@@ -31,28 +32,46 @@ static void runWlp()
wlpPid = atoi(buff);
}
+static gboolean exitDialogResult(GtkWidget *btn, GdkEvent *event, gpointer userdata)
+{
+ if(userdata != NULL)
+ {
+ killWlp();
+ g_application_quit(G_APPLICATION(userdata));
+ }
+ else
+ {
+ gtk_widget_set_visible(exitDialog, 0);
+ }
+}
+
static gboolean exitClicked(GtkWidget *btn, GdkEvent *event, gpointer userdata)
{
- killWlp();
- g_application_quit(G_APPLICATION(userdata));
+ gtk_widget_set_visible(exitDialog, 1);
}
static gboolean deleted(GtkWidget *window, GdkEvent *event, gpointer userdata)
{
- gtk_widget_hide(window);
+ gtk_widget_set_visible(window,0);
}
static void activate(GtkApplication *app, gpointer userdata)
{
builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+
GtkWidget *window = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
- if (window == NULL) printf("wnd not found\n");
-
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(deleted), NULL);
- GtkWidget *exitBtn = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ExitBtn");
+ exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
+
+ GtkWidget *exitDialogYesBtn =(GtkWidget *)gtk_builder_get_object(builder, "ExitDialog_Yes");
+ g_signal_connect(G_OBJECT(exitDialogYesBtn), "clicked", G_CALLBACK(exitDialogResult), app);
+ GtkWidget *exitDialogNoBtn =(GtkWidget *)gtk_builder_get_object(builder, "ExitDialog_No");
+ g_signal_connect(G_OBJECT(exitDialogNoBtn), "clicked", G_CALLBACK(exitDialogResult), NULL);
+ GtkWidget *exitBtn = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ExitBtn");
g_signal_connect(G_OBJECT(exitBtn), "clicked", G_CALLBACK(exitClicked), app);
+
gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
gtk_widget_set_visible(window, 1);
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 173c979..7556ee1 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -15,7 +15,7 @@
False
end
-
+
Yes
True
True
@@ -28,7 +28,7 @@
-
+
No
True
True
From 99837c73e420a8799fd1aa189f8897045c71ddc1 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sun, 31 Dec 2023 23:10:56 +0000
Subject: [PATCH 07/36] Monitor scanner
---
src/core/CMakeLists.txt | 15 ++
src/core/main.c | 77 ++++-----
src/core/main.h | 41 +++++
src/core/monitorScanner.c | 31 ++++
src/core/windowHandlers.c | 48 ++++++
src/window_templates/main.glade | 285 ++++++++++++++++++++++----------
6 files changed, 369 insertions(+), 128 deletions(-)
create mode 100644 src/core/main.h
create mode 100644 src/core/monitorScanner.c
create mode 100644 src/core/windowHandlers.c
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f59c767..3921755 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,5 +1,7 @@
set(_SOURCE_FILES
main.c
+ windowHandlers.c
+ monitorScanner.c
)
# Windows resource file
@@ -16,6 +18,17 @@ if(_UNAME STREQUAL "WIN32")
list(APPEND _SOURCE_FILES "resource.rc")
endif()
+if (_UNAME STREQUAL "LINUX")
+ # X11 and Xrandr dependency
+ include(FindX11)
+
+ list(APPEND _INCLUDE_DIRS ${X11_INCLUDE_DIR})
+ list(APPEND _LIBS ${X11_LIBRARIES})
+
+ list(APPEND _INCLUDE_DIRS ${X11_Xrandr_INCLUDE_PATH})
+ list(APPEND _LIBS ${X11_Xrandr_LIB})
+endif()
+
# GTK dependency
find_package (PkgConfig REQUIRED)
pkg_check_modules (GTK3 REQUIRED gtk+-3.0)
@@ -33,6 +46,8 @@ if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
endif()
+set_target_properties(lwp PROPERTIES ENABLE_EXPORTS on)
+
target_compile_definitions(lwp PUBLIC __${_UNAME})
target_include_directories(lwp PUBLIC ${_INCLUDE_DIRS})
target_link_libraries(lwp PRIVATE ${_LIBS})
diff --git a/src/core/main.c b/src/core/main.c
index d62e5af..69761a8 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1,4 +1,4 @@
-#include
+#include "main.h"
#ifdef __WIN32
#define MAIN_WINDOW_TEMPLATE_PATH ""
@@ -8,12 +8,18 @@
#define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
#endif
+GtkApplication *app = NULL;
GtkBuilder *builder = NULL;
+
+GtkWidget *mainWnd = NULL;
GtkWidget *exitDialog = NULL;
+GtkWidget *wallpaperMgrWnd = NULL;
+GtkWidget *screenWnd = NULL;
+
static FILE *wlpProcess = NULL;
-int wlpPid = 0;
+static int wlpPid = 0;
-static void killWlp()
+void killWlp()
{
if(wlpPid != 0)
kill(wlpPid, SIGINT);
@@ -32,58 +38,39 @@ static void runWlp()
wlpPid = atoi(buff);
}
-static gboolean exitDialogResult(GtkWidget *btn, GdkEvent *event, gpointer userdata)
-{
- if(userdata != NULL)
- {
- killWlp();
- g_application_quit(G_APPLICATION(userdata));
- }
- else
- {
- gtk_widget_set_visible(exitDialog, 0);
- }
-}
-
-static gboolean exitClicked(GtkWidget *btn, GdkEvent *event, gpointer userdata)
-{
- gtk_widget_set_visible(exitDialog, 1);
-}
-
-static gboolean deleted(GtkWidget *window, GdkEvent *event, gpointer userdata)
-{
- gtk_widget_set_visible(window,0);
-}
-
static void activate(GtkApplication *app, gpointer userdata)
{
- builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
-
- GtkWidget *window = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
- g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(deleted), NULL);
-
- exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
+ static int alreadyRunning = 0;
- GtkWidget *exitDialogYesBtn =(GtkWidget *)gtk_builder_get_object(builder, "ExitDialog_Yes");
- g_signal_connect(G_OBJECT(exitDialogYesBtn), "clicked", G_CALLBACK(exitDialogResult), app);
- GtkWidget *exitDialogNoBtn =(GtkWidget *)gtk_builder_get_object(builder, "ExitDialog_No");
- g_signal_connect(G_OBJECT(exitDialogNoBtn), "clicked", G_CALLBACK(exitDialogResult), NULL);
-
- GtkWidget *exitBtn = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ExitBtn");
- g_signal_connect(G_OBJECT(exitBtn), "clicked", G_CALLBACK(exitClicked), app);
-
-
- gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app));
- gtk_widget_set_visible(window, 1);
+ if(!alreadyRunning)
+ {
+ alreadyRunning = 1;
+
+ builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+ gtk_builder_connect_signals(builder, NULL);
+
+ mainWnd = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
+ exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
+ wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
+ screenWnd = (GtkWidget *)gtk_builder_get_object(builder, "ScreenWindow");
+
+ gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(screenWnd), GTK_APPLICATION(app));
+ runWlp();
+ }
- runWlp();
+ gtk_widget_set_visible(mainWnd, 1);
}
int main(int argc, char *argv[])
{
- GtkApplication *app;
int status;
+ Monitor *monitors = scanMonitors();
+ free(monitors);
+
app = gtk_application_new ("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
diff --git a/src/core/main.h b/src/core/main.h
new file mode 100644
index 0000000..c978773
--- /dev/null
+++ b/src/core/main.h
@@ -0,0 +1,41 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#include
+
+#define MONITOR_NAME_MAX 100
+
+typedef struct
+{
+ int x;
+ int y;
+ int w;
+ int h;
+} Bounds;
+
+typedef struct
+{
+ int set;
+ char wlpPath[PATH_MAX];
+ Bounds wlpBounds;
+} MonitorConfig;
+
+typedef struct
+{
+ char name[MONITOR_NAME_MAX];
+ Bounds bounds;
+ MonitorConfig config;
+} Monitor;
+
+extern GtkApplication *app;
+
+extern GtkWidget *mainWnd;
+extern GtkWidget *exitDialog;
+extern GtkWidget *wallpaperMgrWnd;
+extern GtkWidget *screenWnd;
+
+void killWlp();
+
+Monitor* scanMonitors();
+
+#endif
\ No newline at end of file
diff --git a/src/core/monitorScanner.c b/src/core/monitorScanner.c
new file mode 100644
index 0000000..7e160ba
--- /dev/null
+++ b/src/core/monitorScanner.c
@@ -0,0 +1,31 @@
+#include "main.h"
+
+#include
+#include
+#include
+#include
+
+Monitor* scanMonitors()
+{
+ int monitorCount;
+ Display *display = XOpenDisplay((getenv("DISPLAY")));
+ Window wnd = DefaultRootWindow(display);
+ XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
+
+ Monitor *m = malloc(sizeof(Monitor) * monitorCount);
+
+ int i = 0;
+ while (i < monitorCount)
+ {
+ snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
+ m[i].bounds.x = info->x;
+ m[i].bounds.y = info->y;
+ m[i].bounds.w = info->width;
+ m[i].bounds.h = info->height;
+ m[i].config.set = 0;
+
+ info++;
+ i++;
+ }
+ return m;
+}
\ No newline at end of file
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
new file mode 100644
index 0000000..91449c7
--- /dev/null
+++ b/src/core/windowHandlers.c
@@ -0,0 +1,48 @@
+#include "main.h"
+
+// Exit Dialog handlers
+
+G_MODULE_EXPORT void ExitDialogClose()
+{
+ gtk_widget_set_visible(exitDialog,0);
+}
+
+G_MODULE_EXPORT void ExitDialog_No()
+{
+ gtk_widget_set_visible(exitDialog, 0);
+}
+
+G_MODULE_EXPORT void ExitDialog_Yes()
+{
+ killWlp();
+ g_application_quit(G_APPLICATION(app));
+}
+
+// Main Window handlers
+
+G_MODULE_EXPORT void MainWindow_ManageWallpapersBtnClick()
+{
+ gtk_widget_set_visible(wallpaperMgrWnd, 1);
+}
+
+G_MODULE_EXPORT void MainWindow_ExitBtnClick()
+{
+ gtk_widget_set_visible(exitDialog, 1);
+}
+
+G_MODULE_EXPORT void MainWindowClose()
+{
+ gtk_widget_set_visible(mainWnd,0);
+}
+
+// Wallpapaer Manager Window handlers
+
+G_MODULE_EXPORT void WallpaperManagerWindowClose()
+{
+ gtk_widget_set_visible(wallpaperMgrWnd,0);
+}
+
+G_MODULE_EXPORT void ScreenWindowClose()
+{
+ gtk_widget_set_visible(screenWnd,0);
+}
\ No newline at end of file
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 7556ee1..ad77c14 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -4,7 +4,10 @@
False
+ False
dialog
+ False
+
False
@@ -15,11 +18,12 @@
False
end
-
+
Yes
True
True
True
+
True
@@ -28,11 +32,12 @@
-
+
No
True
True
True
+
True
@@ -67,6 +72,7 @@
False
800
600
+
True
@@ -76,101 +82,35 @@
True
False
+ vertical
True
False
- 11
- v 1.0.0
-
-
- False
- True
- 1
-
-
-
-
- Github page
- True
- True
- True
- none
- https://github.com/jszczerbinsky/lwp
+ 10
+ 10
+ Layered WallPaper
+ center
+
+
+
False
True
- end
- 2
-
-
-
-
- False
- True
- end
- 0
-
-
-
-
- True
- False
-
-
- True
- False
- vertical
-
-
- True
- False
- 10
- 10
- Layered WallPaper
- center
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- Enhance your desktop experiance
- center
-
-
- False
- True
- 1
-
-
-
-
- True
- True
0
-
- Exit
+
True
- True
- True
+ False
+ Enhance your desktop experiance
+ center
False
True
- end
1
@@ -178,7 +118,7 @@
False
True
- 1
+ 0
@@ -187,7 +127,7 @@
False
120
120
- 50
+ 8
vertical
@@ -207,9 +147,11 @@
-
+
True
False
+ 40
+ 40
True
@@ -253,6 +195,183 @@
True
True
+ 1
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 11
+ v 1.0.0
+
+
+ False
+ True
+ 1
+
+
+
+
+ Github page
+ True
+ True
+ True
+ none
+ https://github.com/jszczerbinsky/lwp
+
+
+ False
+ True
+ end
+ 2
+
+
+
+
+ False
+ True
+ end
+ 2
+
+
+
+
+ True
+ False
+ center
+
+
+ Manage wallpapers
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ Exit
+ True
+ True
+ True
+
+
+
+ False
+ True
+ end
+ 1
+
+
+
+
+ False
+ True
+ 3
+
+
+
+
+
+
+ False
+
+
+
+ True
+ False
+ vertical
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 10
+ 10
+ Manage wallpapers
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ center
+
+
+ Add
+ True
+ True
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ Remove
+ True
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
2
From ff6042627ba2bf990fdd1e3f55e7766d4d48497d Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Tue, 2 Jan 2024 10:59:45 +0000
Subject: [PATCH 08/36] Monitor list box
---
src/core/main.c | 131 +++++++++++++++++++-------------
src/core/main.h | 27 +++----
src/core/monitorScanner.c | 5 +-
src/core/windowHandlers.c | 36 +++------
src/window_templates/main.glade | 32 --------
5 files changed, 107 insertions(+), 124 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 69761a8..d951a83 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1,80 +1,109 @@
#include "main.h"
#ifdef __WIN32
- #define MAIN_WINDOW_TEMPLATE_PATH ""
+#define MAIN_WINDOW_TEMPLATE_PATH ""
#elif __DARWIN
- #define MAIN_WINDOW_TEMPLATE_PATH ""
+#define MAIN_WINDOW_TEMPLATE_PATH ""
#else
- #define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
+#define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
#endif
-GtkApplication *app = NULL;
-GtkBuilder *builder = NULL;
+GtkApplication *app = NULL;
+GtkBuilder *builder = NULL;
-GtkWidget *mainWnd = NULL;
-GtkWidget *exitDialog = NULL;
+GtkWidget *mainWnd = NULL;
+GtkWidget *exitDialog = NULL;
GtkWidget *wallpaperMgrWnd = NULL;
-GtkWidget *screenWnd = NULL;
+GtkWidget *screenWnd = NULL;
+GtkWidget *screenListBox = NULL;
static FILE *wlpProcess = NULL;
-static int wlpPid = 0;
+static int wlpPid = 0;
void killWlp()
{
- if(wlpPid != 0)
- kill(wlpPid, SIGINT);
- if(wlpProcess != NULL)
- pclose(wlpProcess);
+ if (wlpPid != 0) kill(wlpPid, SIGINT);
+ if (wlpProcess != NULL) pclose(wlpProcess);
- wlpPid = 0;
- wlpProcess = NULL;
+ wlpPid = 0;
+ wlpProcess = NULL;
}
static void runWlp()
{
- wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
- char buff[10];
- fgets(buff, sizeof(buff) - 1, wlpProcess);
- wlpPid = atoi(buff);
+ wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
+ char buff[10];
+ fgets(buff, sizeof(buff) - 1, wlpProcess);
+ wlpPid = atoi(buff);
+}
+
+static void reloadScreenListBox()
+{
+ GList *rows = gtk_container_get_children(GTK_CONTAINER(screenListBox));
+
+ GList *ptr = rows;
+ while (ptr)
+ {
+ gtk_container_remove(GTK_CONTAINER(screenListBox), ptr->data);
+ ptr = ptr->next;
+ }
+
+ g_list_free(rows);
+
+ int monitorsCount;
+ Monitor *monitors;
+
+ monitors = scanMonitors(&monitorsCount);
+
+ for (int i = 0; i < 1; i++)
+ {
+ GtkWidget *label = gtk_label_new(monitors[i].name);
+ GtkWidget *row = gtk_list_box_row_new();
+ gtk_container_add(GTK_CONTAINER(row), label);
+
+ gtk_list_box_insert(GTK_LIST_BOX(screenListBox), row, 0);
+ gtk_widget_show_all(row);
+ }
}
static void activate(GtkApplication *app, gpointer userdata)
{
- static int alreadyRunning = 0;
-
- if(!alreadyRunning)
- {
- alreadyRunning = 1;
-
- builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
- gtk_builder_connect_signals(builder, NULL);
-
- mainWnd = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
- exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
- wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
- screenWnd = (GtkWidget *)gtk_builder_get_object(builder, "ScreenWindow");
-
- gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
- gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
- gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
- gtk_window_set_application(GTK_WINDOW(screenWnd), GTK_APPLICATION(app));
- runWlp();
- }
-
- gtk_widget_set_visible(mainWnd, 1);
+ static int alreadyRunning = 0;
+
+ if (!alreadyRunning)
+ {
+ alreadyRunning = 1;
+
+ builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+ gtk_builder_connect_signals(builder, NULL);
+
+ mainWnd = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
+ exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
+ wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
+ screenWnd = (GtkWidget *)gtk_builder_get_object(builder, "ScreenWindow");
+ screenListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ScreenListBox");
+
+ gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(screenWnd), GTK_APPLICATION(app));
+
+ runWlp();
+ }
+
+ reloadScreenListBox();
+
+ gtk_widget_set_visible(mainWnd, 1);
}
int main(int argc, char *argv[])
{
- int status;
+ int status;
- Monitor *monitors = scanMonitors();
- free(monitors);
+ app = gtk_application_new("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
+ g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
+ status = g_application_run(G_APPLICATION(app), argc, argv);
+ g_object_unref(app);
- app = gtk_application_new ("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
- status = g_application_run (G_APPLICATION (app), argc, argv);
- g_object_unref (app);
-
- return status;
-}
\ No newline at end of file
+ return status;
+}
diff --git a/src/core/main.h b/src/core/main.h
index c978773..2c2e46a 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -7,35 +7,36 @@
typedef struct
{
- int x;
- int y;
- int w;
- int h;
+ int x;
+ int y;
+ int w;
+ int h;
} Bounds;
typedef struct
{
- int set;
- char wlpPath[PATH_MAX];
- Bounds wlpBounds;
+ int set;
+ char wlpPath[PATH_MAX];
+ Bounds wlpBounds;
} MonitorConfig;
typedef struct
{
- char name[MONITOR_NAME_MAX];
- Bounds bounds;
- MonitorConfig config;
+ char name[MONITOR_NAME_MAX];
+ Bounds bounds;
+ MonitorConfig config;
} Monitor;
extern GtkApplication *app;
-extern GtkWidget *mainWnd;
+extern GtkWidget *mainWnd;
extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
extern GtkWidget *screenWnd;
+extern GtkWidget *screenListBox;
void killWlp();
-Monitor* scanMonitors();
+Monitor *scanMonitors(int *count);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/core/monitorScanner.c b/src/core/monitorScanner.c
index 7e160ba..28f5ebc 100644
--- a/src/core/monitorScanner.c
+++ b/src/core/monitorScanner.c
@@ -5,7 +5,7 @@
#include
#include
-Monitor* scanMonitors()
+Monitor* scanMonitors(int *count)
{
int monitorCount;
Display *display = XOpenDisplay((getenv("DISPLAY")));
@@ -27,5 +27,8 @@ Monitor* scanMonitors()
info++;
i++;
}
+
+ *count = monitorCount;
+
return m;
}
\ No newline at end of file
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 91449c7..462fef9 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -2,47 +2,29 @@
// Exit Dialog handlers
-G_MODULE_EXPORT void ExitDialogClose()
-{
- gtk_widget_set_visible(exitDialog,0);
-}
+G_MODULE_EXPORT void ExitDialogClose() { gtk_widget_set_visible(exitDialog, 0); }
-G_MODULE_EXPORT void ExitDialog_No()
-{
- gtk_widget_set_visible(exitDialog, 0);
-}
+G_MODULE_EXPORT void ExitDialog_No() { gtk_widget_set_visible(exitDialog, 0); }
G_MODULE_EXPORT void ExitDialog_Yes()
{
- killWlp();
- g_application_quit(G_APPLICATION(app));
+ killWlp();
+ g_application_quit(G_APPLICATION(app));
}
// Main Window handlers
G_MODULE_EXPORT void MainWindow_ManageWallpapersBtnClick()
{
- gtk_widget_set_visible(wallpaperMgrWnd, 1);
+ gtk_widget_set_visible(wallpaperMgrWnd, 1);
}
-G_MODULE_EXPORT void MainWindow_ExitBtnClick()
-{
- gtk_widget_set_visible(exitDialog, 1);
-}
+G_MODULE_EXPORT void MainWindow_ExitBtnClick() { gtk_widget_set_visible(exitDialog, 1); }
-G_MODULE_EXPORT void MainWindowClose()
-{
- gtk_widget_set_visible(mainWnd,0);
-}
+G_MODULE_EXPORT void MainWindowClose() { gtk_widget_set_visible(mainWnd, 0); }
// Wallpapaer Manager Window handlers
-G_MODULE_EXPORT void WallpaperManagerWindowClose()
-{
- gtk_widget_set_visible(wallpaperMgrWnd,0);
-}
+G_MODULE_EXPORT void WallpaperManagerWindowClose() { gtk_widget_set_visible(wallpaperMgrWnd, 0); }
-G_MODULE_EXPORT void ScreenWindowClose()
-{
- gtk_widget_set_visible(screenWnd,0);
-}
\ No newline at end of file
+G_MODULE_EXPORT void ScreenWindowClose() { gtk_widget_set_visible(screenWnd, 0); }
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index ad77c14..831f258 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -152,38 +152,6 @@
False
40
40
-
-
- True
- True
-
-
- True
- False
- start
- 10
- 10
- Monitor 2
-
-
-
-
-
-
- True
- True
-
-
- True
- False
- start
- 10
- 10
- Monitor 1
-
-
-
-
False
From e3475a52ae6ba192c144837441e4b3a4b6a961af Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Tue, 2 Jan 2024 12:00:28 +0000
Subject: [PATCH 09/36] Changed screenWindow to monitorWindow
---
src/core/main.c | 20 ++++++++++----------
src/core/main.h | 3 +--
src/core/windowHandlers.c | 4 +++-
src/window_templates/main.glade | 22 ++++++++++++++++++----
4 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index d951a83..6f0ce76 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -14,8 +14,8 @@ GtkBuilder *builder = NULL;
GtkWidget *mainWnd = NULL;
GtkWidget *exitDialog = NULL;
GtkWidget *wallpaperMgrWnd = NULL;
-GtkWidget *screenWnd = NULL;
-GtkWidget *screenListBox = NULL;
+GtkWidget *monitorWnd = NULL;
+GtkWidget *monitorListBox = NULL;
static FILE *wlpProcess = NULL;
static int wlpPid = 0;
@@ -37,14 +37,14 @@ static void runWlp()
wlpPid = atoi(buff);
}
-static void reloadScreenListBox()
+static void reloadMonitorListBox()
{
- GList *rows = gtk_container_get_children(GTK_CONTAINER(screenListBox));
+ GList *rows = gtk_container_get_children(GTK_CONTAINER(monitorListBox));
GList *ptr = rows;
while (ptr)
{
- gtk_container_remove(GTK_CONTAINER(screenListBox), ptr->data);
+ gtk_container_remove(GTK_CONTAINER(monitorListBox), ptr->data);
ptr = ptr->next;
}
@@ -61,7 +61,7 @@ static void reloadScreenListBox()
GtkWidget *row = gtk_list_box_row_new();
gtk_container_add(GTK_CONTAINER(row), label);
- gtk_list_box_insert(GTK_LIST_BOX(screenListBox), row, 0);
+ gtk_list_box_insert(GTK_LIST_BOX(monitorListBox), row, 0);
gtk_widget_show_all(row);
}
}
@@ -80,18 +80,18 @@ static void activate(GtkApplication *app, gpointer userdata)
mainWnd = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
- screenWnd = (GtkWidget *)gtk_builder_get_object(builder, "ScreenWindow");
- screenListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_ScreenListBox");
+ monitorWnd = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow");
+ monitorListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_MonitorListBox");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
- gtk_window_set_application(GTK_WINDOW(screenWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(monitorWnd), GTK_APPLICATION(app));
runWlp();
}
- reloadScreenListBox();
+ reloadMonitorListBox();
gtk_widget_set_visible(mainWnd, 1);
}
diff --git a/src/core/main.h b/src/core/main.h
index 2c2e46a..fa2a9de 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -32,8 +32,7 @@ extern GtkApplication *app;
extern GtkWidget *mainWnd;
extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
-extern GtkWidget *screenWnd;
-extern GtkWidget *screenListBox;
+extern GtkWidget *monitorWnd;
void killWlp();
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 462fef9..9a3233f 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -19,6 +19,8 @@ G_MODULE_EXPORT void MainWindow_ManageWallpapersBtnClick()
gtk_widget_set_visible(wallpaperMgrWnd, 1);
}
+G_MODULE_EXPORT void MainWindow_MonitorEditBtnClick() { gtk_widget_set_visible(monitorWnd, 1); }
+
G_MODULE_EXPORT void MainWindow_ExitBtnClick() { gtk_widget_set_visible(exitDialog, 1); }
G_MODULE_EXPORT void MainWindowClose() { gtk_widget_set_visible(mainWnd, 0); }
@@ -27,4 +29,4 @@ G_MODULE_EXPORT void MainWindowClose() { gtk_widget_set_visible(mainWnd, 0); }
G_MODULE_EXPORT void WallpaperManagerWindowClose() { gtk_widget_set_visible(wallpaperMgrWnd, 0); }
-G_MODULE_EXPORT void ScreenWindowClose() { gtk_widget_set_visible(screenWnd, 0); }
+G_MODULE_EXPORT void MonitorWindowClose() { gtk_widget_set_visible(monitorWnd, 0); }
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 831f258..5c7c2f3 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -135,7 +135,7 @@
False
5
5
- Setup your screens
+ Setup your monitors
@@ -147,7 +147,7 @@
-
+
True
False
40
@@ -159,6 +159,20 @@
1
+
+
+ Edit settings
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 2
+
+
True
@@ -251,9 +265,9 @@
-
+
False
-
+
True
From 9f8d8c86f999f391a922cf8a111f27e364149d6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Tue, 2 Jan 2024 18:29:34 +0100
Subject: [PATCH 10/36] Building on Windows
---
CMakeLists.txt | 26 +++++++++++++++-----------
distributeDLLs.sh | 18 ++++++++++++++++++
src/core/CMakeLists.txt | 1 +
src/core/main.c | 4 +++-
src/core/monitorScanner.c | 14 +++++++++++++-
src/{wlp => core}/resource.template.rc | 0
src/wlp/CMakeLists.txt | 14 --------------
src/wlp/main.c | 4 ++++
src/wlp/window.c | 2 +-
9 files changed, 55 insertions(+), 28 deletions(-)
create mode 100644 distributeDLLs.sh
rename src/{wlp => core}/resource.template.rc (100%)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d73e6f..9069ed9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,10 +8,12 @@ project(lwp
# Detect the platform
if (APPLE)
set(_UNAME "DARWIN")
-elseif (WIN32)
+elseif (MSYS OR MINGW)
set(_UNAME "WIN32")
-else()
+elseif(UNIX)
set(_UNAME "LINUX")
+else()
+ message(FATAL_ERROR "Unsupported platform")
endif()
# Detect version
@@ -46,12 +48,14 @@ add_subdirectory(src/wlp)
link_directories(src/wlp)
add_subdirectory(src/core)
-link_directories(src/core)
+link_directories(src/core)
# Installation rules
if(_UNAME STREQUAL "WIN32")
install(DIRECTORY wallpapers
DESTINATION .)
+ install(DIRECTORY build/dlls/
+ DESTINATION .)
install(DIRECTORY src/window_templates
DESTINATION .)
install(FILES LICENSE.txt
@@ -73,15 +77,15 @@ elseif(_UNAME STREQUAL "LINUX")
TYPE SYSCONF
RENAME lwp.cfg)
else()
- install(DIRECTORY wallpapers
- DESTINATION Layered_WallPaper)
- install(DIRECTORY src/window_templates
- DESTINATION Layered_WallPaper)
- install(FILES LICENSE.txt
- DESTINATION Layered_WallPaper)
- install(FILES ${_DEFAULT_CONFIG_FILE}
+ install(DIRECTORY wallpapers
+ DESTINATION Layered_WallPaper)
+ install(DIRECTORY src/window_templates
+ DESTINATION Layered_WallPaper)
+ install(FILES LICENSE.txt
+ DESTINATION Layered_WallPaper)
+ install(FILES ${_DEFAULT_CONFIG_FILE}
DESTINATION Layered_WallPaper
- RENAME lwp.cfg)
+ RENAME lwp.cfg)
install(FILES lwp.template.plist
DESTINATION Layered_WallPaper)
install (FILES setupPlist.command
diff --git a/distributeDLLs.sh b/distributeDLLs.sh
new file mode 100644
index 0000000..e18b501
--- /dev/null
+++ b/distributeDLLs.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+echo
+PS3='Choose the correct version of gdbus: '
+options=("/mingw64/bin/gdbus.exe" "/mingw32/bin/gdbus.exe")
+select opt in "${options[@]}"
+do
+ echo "Preparing gdbus.exe..."
+ cp $opt ./dlls/
+ break;
+done
+
+echo "Preparing DLLs..."
+
+mkdir -p dlls
+ldd ./src/core/lwp.exe | grep '\/mingw.*\.dll' -o | xargs -I{} cp "{}" ./dlls/
+
+echo "Done"
\ No newline at end of file
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3921755..542ddb2 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -35,6 +35,7 @@ pkg_check_modules (GTK3 REQUIRED gtk+-3.0)
list(APPEND _INCLUDE_DIRS ${GTK3_INCLUDE_DIRS})
list(APPEND _LIBS ${GTK3_LINK_LIBRARIES})
+
# Main executable
if (_UNAME STREQUAL "DARWIN")
add_executable(lwp MACOSX_BUNDLE ${_SOURCE_FILES})
diff --git a/src/core/main.c b/src/core/main.c
index 6f0ce76..8267ca1 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1,7 +1,7 @@
#include "main.h"
#ifdef __WIN32
-#define MAIN_WINDOW_TEMPLATE_PATH ""
+#define MAIN_WINDOW_TEMPLATE_PATH "./window_templates/main.glade"
#elif __DARWIN
#define MAIN_WINDOW_TEMPLATE_PATH ""
#else
@@ -22,11 +22,13 @@ static int wlpPid = 0;
void killWlp()
{
+ #ifndef __WIN32
if (wlpPid != 0) kill(wlpPid, SIGINT);
if (wlpProcess != NULL) pclose(wlpProcess);
wlpPid = 0;
wlpProcess = NULL;
+ #endif
}
static void runWlp()
diff --git a/src/core/monitorScanner.c b/src/core/monitorScanner.c
index 28f5ebc..ba5c0dd 100644
--- a/src/core/monitorScanner.c
+++ b/src/core/monitorScanner.c
@@ -2,9 +2,20 @@
#include
#include
+
+#ifndef __WIN32
#include
#include
+#endif
+
+#ifdef __WIN32
+Monitor* scanMonitors(int *count)
+{
+ return NULL;
+}
+#endif
+#ifdef LINUX
Monitor* scanMonitors(int *count)
{
int monitorCount;
@@ -31,4 +42,5 @@ Monitor* scanMonitors(int *count)
*count = monitorCount;
return m;
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/wlp/resource.template.rc b/src/core/resource.template.rc
similarity index 100%
rename from src/wlp/resource.template.rc
rename to src/core/resource.template.rc
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 64e71d8..7ba99e0 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -9,20 +9,6 @@ set(_SOURCE_FILES
wallpaper.c
window.c
)
-
-# Windows resource file
-if(_UNAME STREQUAL "WIN32")
- if(MINGW)
- set(CMAKE_RC_COMPILER_INIT windres)
- ENABLE_LANGUAGE(RC)
- SET(CMAKE_RC_COMPILE_OBJECT
- " -O coff -i -o ")
- endif(MINGW)
-
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resource.template.rc ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
- @ONLY)
- list(APPEND _SOURCE_FILES "resource.rc")
-endif()
# SDL2 dependency
find_package(SDL2 REQUIRED CONFIG)
diff --git a/src/wlp/main.c b/src/wlp/main.c
index 0f68eb6..3fd68e5 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -65,10 +65,12 @@ static void atExit()
SDL_Quit();
}
+#ifndef __WIN32
void exitSignalHandler(int s)
{
exit(0);
}
+#endif
int main(int argc, char *argv[])
{
@@ -76,7 +78,9 @@ int main(int argc, char *argv[])
sprintf(pidStr, "%d\0", getpid());
fputs(pidStr, stdout);
+#ifndef __WIN32
signal(SIGINT, exitSignalHandler);
+#endif
lwpLog(LOG_INFO, "Starting Layered WallPaper");
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 68b6228..2a4e61f 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -104,7 +104,7 @@ void initTrayIcon()
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(0, CLASS_NAME, L"", WS_OVERLcfgEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ HWND hWnd = CreateWindowEx(0, CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
// Create tray icon
From 27f41e81ae25bb5a0abb26b0b837518275b5947e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Thu, 4 Jan 2024 11:15:51 +0100
Subject: [PATCH 11/36] Windows wlp subprocess and monitor scanner
---
distributeDLLs.sh | 3 +-
src/common.h | 4 +++
src/core/CMakeLists.txt | 1 +
src/core/main.c | 22 -------------
src/core/main.h | 1 +
src/core/monitorScanner.c | 42 ++++++++++++++++++++----
src/core/wlp.c | 67 +++++++++++++++++++++++++++++++++++++++
src/wlp/main.c | 6 ++--
src/wlp/main.h | 4 +--
9 files changed, 115 insertions(+), 35 deletions(-)
create mode 100644 src/common.h
create mode 100644 src/core/wlp.c
diff --git a/distributeDLLs.sh b/distributeDLLs.sh
index e18b501..ccfcab3 100644
--- a/distributeDLLs.sh
+++ b/distributeDLLs.sh
@@ -1,5 +1,7 @@
#!/bin/bash
+mkdir -p dlls
+
echo
PS3='Choose the correct version of gdbus: '
options=("/mingw64/bin/gdbus.exe" "/mingw32/bin/gdbus.exe")
@@ -12,7 +14,6 @@ done
echo "Preparing DLLs..."
-mkdir -p dlls
ldd ./src/core/lwp.exe | grep '\/mingw.*\.dll' -o | xargs -I{} cp "{}" ./dlls/
echo "Done"
\ No newline at end of file
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 0000000..05ce8e1
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,4 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#endif
\ No newline at end of file
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 542ddb2..8722b68 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -2,6 +2,7 @@ set(_SOURCE_FILES
main.c
windowHandlers.c
monitorScanner.c
+ wlp.c
)
# Windows resource file
diff --git a/src/core/main.c b/src/core/main.c
index 8267ca1..39e3ef8 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -17,28 +17,6 @@ GtkWidget *wallpaperMgrWnd = NULL;
GtkWidget *monitorWnd = NULL;
GtkWidget *monitorListBox = NULL;
-static FILE *wlpProcess = NULL;
-static int wlpPid = 0;
-
-void killWlp()
-{
- #ifndef __WIN32
- if (wlpPid != 0) kill(wlpPid, SIGINT);
- if (wlpProcess != NULL) pclose(wlpProcess);
-
- wlpPid = 0;
- wlpProcess = NULL;
- #endif
-}
-
-static void runWlp()
-{
- wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
- char buff[10];
- fgets(buff, sizeof(buff) - 1, wlpProcess);
- wlpPid = atoi(buff);
-}
-
static void reloadMonitorListBox()
{
GList *rows = gtk_container_get_children(GTK_CONTAINER(monitorListBox));
diff --git a/src/core/main.h b/src/core/main.h
index fa2a9de..d4b6317 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -34,6 +34,7 @@ extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
extern GtkWidget *monitorWnd;
+void runWlp();
void killWlp();
Monitor *scanMonitors(int *count);
diff --git a/src/core/monitorScanner.c b/src/core/monitorScanner.c
index ba5c0dd..0745bf7 100644
--- a/src/core/monitorScanner.c
+++ b/src/core/monitorScanner.c
@@ -3,27 +3,55 @@
#include
#include
-#ifndef __WIN32
+#ifdef __WIN32
+#include
+#else
#include
#include
#endif
#ifdef __WIN32
-Monitor* scanMonitors(int *count)
+int monitorEnumIndex = 0;
+
+BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
{
- return NULL;
+ MONITORINFO info;
+ info.cbSize = sizeof(MONITORINFO);
+
+ GetMonitorInfo(monitor, &info);
+
+ Monitor *m = (Monitor*)param;
+
+ snprintf(m[monitorEnumIndex].name, MONITOR_NAME_MAX, "Monitor %d%s", monitorEnumIndex + 1, info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : "");
+ m[monitorEnumIndex].bounds.x = info.rcWork.left;
+ m[monitorEnumIndex].bounds.y = info.rcWork.top;
+ m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
+ m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
+ m[monitorEnumIndex].config.set = 0;
+
+ monitorEnumIndex++;
+ return TRUE;
}
#endif
-#ifdef LINUX
Monitor* scanMonitors(int *count)
{
int monitorCount;
+ Monitor *m = NULL;
+
+#ifdef __WIN32
+ monitorCount = GetSystemMetrics(SM_CMONITORS);
+ m = malloc(sizeof(Monitor) * monitorCount);
+
+ monitorEnumIndex = 0;
+ EnumDisplayMonitors(NULL, NULL, &monitorenumproc, (LPARAM)m);
+
+#else
Display *display = XOpenDisplay((getenv("DISPLAY")));
Window wnd = DefaultRootWindow(display);
XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
- Monitor *m = malloc(sizeof(Monitor) * monitorCount);
+ m = malloc(sizeof(Monitor) * monitorCount);
int i = 0;
while (i < monitorCount)
@@ -41,6 +69,6 @@ Monitor* scanMonitors(int *count)
*count = monitorCount;
+#endif
return m;
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/core/wlp.c b/src/core/wlp.c
new file mode 100644
index 0000000..0e6b032
--- /dev/null
+++ b/src/core/wlp.c
@@ -0,0 +1,67 @@
+#include "main.h"
+
+#ifdef __WIN32
+#include
+#include
+#endif
+
+#ifdef __WIN32
+static HANDLE hWlpProcess = NULL;
+#else
+static FILE *wlpProcess = NULL;
+static int wlpPid = 0;
+#endif
+
+void killWlp()
+{
+#ifdef __WIN32
+ TerminateProcess(hWlpProcess, 0);
+#else
+ if (wlpPid != 0) kill(wlpPid, SIGINT);
+ if (wlpProcess != NULL) pclose(wlpProcess);
+
+ wlpPid = 0;
+ wlpProcess = NULL;
+#endif
+}
+
+void runWlp()
+{
+#ifdef __WIN32
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ si.cb = sizeof(si);
+
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(NULL, path, MAX_PATH);
+ path[_tcslen(path)-4] = '\0';
+ _tcscat(path, TEXT("wlp.exe"));
+ printf("%s\n", path);
+
+ if(CreateProcess(
+ NULL,
+ path,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi
+ ))
+ hWlpProcess = pi.hProcess;
+ else
+ printf("Failed to start a wallpaper subprocess");
+
+
+#else
+ wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
+ char buff[10];
+ fgets(buff, sizeof(buff) - 1, wlpProcess);
+ wlpPid = atoi(buff);
+#endif
+}
\ No newline at end of file
diff --git a/src/wlp/main.c b/src/wlp/main.c
index 3fd68e5..d7b5842 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -65,12 +65,10 @@ static void atExit()
SDL_Quit();
}
-#ifndef __WIN32
void exitSignalHandler(int s)
{
exit(0);
}
-#endif
int main(int argc, char *argv[])
{
@@ -78,7 +76,9 @@ int main(int argc, char *argv[])
sprintf(pidStr, "%d\0", getpid());
fputs(pidStr, stdout);
-#ifndef __WIN32
+#ifdef __WIN32
+ signal(SIGTERM, exitSignalHandler);
+#else
signal(SIGINT, exitSignalHandler);
#endif
diff --git a/src/wlp/main.h b/src/wlp/main.h
index 09de760..71cb43b 100644
--- a/src/wlp/main.h
+++ b/src/wlp/main.h
@@ -8,6 +8,8 @@
#include
#endif
+#include
+
#ifdef __WIN32
#include
#include
@@ -18,14 +20,12 @@
#include
#include
#include
-#include
#elif __LINUX
#include
#include
#include
#include
#include
-#include
#endif
typedef struct
From 079f0d530774dcdeb8192c5ae8eff40ad30c8f8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Thu, 4 Jan 2024 11:51:26 +0100
Subject: [PATCH 12/36] Update compilation steps for Windows in README
---
README.md | 70 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 44 insertions(+), 26 deletions(-)
diff --git a/README.md b/README.md
index 364df25..0869246 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+
# Layered WallPaper
@@ -106,33 +107,50 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
- Layered WallPaper should run immediately after the installation
#### Build from source instead
- - Layered WallPaper is built using [cmake](https://cmake.org/), so You must install it.
- - This project supports `MinGW` and `MSVC` compilers. Using different one could lead to unpredicted behavior. If You want to use `MSVC`, it should be installed with Visual Studio.
- - Download `SDL2` and `SDL2-devel` package for Your compiler from [SDL2 releases](https://github.com/libsdl-org/SDL/releases/latest) and extract them somewhere.
- - You also must install [NSIS](https://nsis.sourceforge.io/Download). It's required to build the installer, which is needed to correctly set the registry keys, that will make Layered WallPaper run on OS startup etc.
- - Clone the repository and create `build` directory
- ```shell
- git clone https://github.com/jszczerbinsky/lwp
- cd lwp
- mkdir -p build
- cd build
- ```
- - Type the following commands, replace square brackets elements with paths to extracted `SDL2` packages, that You've downloaded:
+ To compile Layered WallPaper on Windows you need to install [MSYS2](https://www.msys2.org/). After the installation follow the guide for setting up [GTK development enviroment](https://www.gtk.org/docs/installations/windows#using-gtk-from-msys2-packages). From now on continue using MSYS2 MinGW terminal (make sure you're using `MSYS2 MINGW64`/`MSYS2 MINGW32` instead of `MSYS2`).
+
+##### Install the remaining dependencies
+There is a problem with the newest version of SDL2 on MSYS2 repository (see [issue](https://github.com/haskell-game/sdl2/issues/277)), that leads to a compilation error, thus You should install an older version of SDL2 instead.
+```shell
+# For 64bit:
+curl -O https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-SDL2-2.0.14-2-any.pkg.tar.zst
+pacman -U mingw-w64-x86_64-SDL2-2.0.14-2-any.pkg.tar.zst
+
+# For 32bit:
+curl -O https://repo.msys2.org/mingw/i686/mingw-w64-i686-SDL2-2.0.14-2-any.pkg.tar.zst
+pacman -U mingw-w64-i686-SDL2-2.0.14-2-any.pkg.tar.zst
+```
+You also have to install cmake
+```shell
+# For 64bit:
+pacman -S mingw-w64-x86_64-cmake
- For `MSVC`:
- ```shell
- cmake -G "Visual Studio 17" -DSDL2_DIR=[PATH TO SDL2-MSVC-DEVEL DIRECTORY]\cmake -DSDL2_RUNTIME_DIR=[PATH TO SDL2 RUNTIME DIRECTORY] ../
- cmake --build . --config Release
- cpack
- ```
- For `MinGW`:
- ```shell
- cmake -G "MinGW Makefiles" -DSDL2_DIR=[PATH TO SDL2-MINGW-DEVEL DIRECTORY]\cmake -DSDL2_RUNTIME_DIR=[PATH TO SDL2 RUNTIME DIRECTORY] -DCMAKE_BUILD_TYPE=Release ../
- cmake --build .
- cpack
- ```
- - The installer should appear in `build` directory, that You've created earlier. After completing the installation Layered WallPaper should run immediately.
+# For 32bit:
+pacman -S mingw-w64-i686-cmake
+```
+
+##### Clone the repository
+```shell
+git clone https://github.com/jszczerbinsky/lwp
+cd lwp
+mkdir build
+cd build
+```
+
+##### Compile and install
+- Download [SDL2](https://github.com/libsdl-org/SDL/releases/latest) runtime package and unpack it.
+- Compile the program
+```shell
+# Remember to use unix path format (instead of C:/path/to/dir use /c/path/to/dir)
+cmake -DSDL2_RUNTIME_DIR=/path/to/dir ../
+cmake --build .
+# Prepare the DLLs, that will be shipped with the program.
+# The script is going to ask you which version of gdbus.exe should it use (32bit or 64bit)
+../distributeDLLs.sh
+cpack
+```
+After this the installer should appear in the current directory.
@@ -251,4 +269,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+SOFTWARE.
\ No newline at end of file
From a8f65193348551d6b0b4129956eb4f7ecd3fe8d8 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Mon, 15 Jan 2024 19:34:17 +0000
Subject: [PATCH 13/36] Wallpaper scanner
---
src/common.h | 46 ++++++++++++++++++-
src/common/monitorScanner.c | 80 +++++++++++++++++++++++++++++++++
src/common/wallpaperScanner.c | 47 +++++++++++++++++++
src/core/CMakeLists.txt | 9 ++--
src/core/main.c | 15 ++++---
src/core/main.h | 27 +----------
src/core/monitorScanner.c | 74 ------------------------------
src/core/windowHandlers.c | 20 +++++++++
src/window_templates/main.glade | 3 +-
9 files changed, 210 insertions(+), 111 deletions(-)
create mode 100644 src/common/monitorScanner.c
create mode 100644 src/common/wallpaperScanner.c
delete mode 100644 src/core/monitorScanner.c
diff --git a/src/common.h b/src/common.h
index 05ce8e1..dbce32b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,4 +1,48 @@
#ifndef COMMON_H
#define COMMON_H
-#endif
\ No newline at end of file
+#ifdef __LINUX
+#include
+#elif __DARWIN
+#include
+#else
+#include
+#endif
+
+#define MONITOR_NAME_MAX 100
+#define WALLPAPER_NAME_MAX 100
+
+typedef struct
+{
+ int x;
+ int y;
+ int w;
+ int h;
+} Bounds;
+
+typedef struct
+{
+ int set;
+ char wlpPath[PATH_MAX];
+ Bounds wlpBounds;
+} MonitorConfig;
+
+typedef struct
+{
+ char name[MONITOR_NAME_MAX];
+ Bounds bounds;
+ MonitorConfig config;
+} Monitor;
+
+Monitor *scanMonitors(int *count);
+
+typedef struct
+{
+ char name[WALLPAPER_NAME_MAX];
+ char dirPath[PATH_MAX];
+ int isDefault;
+} WallpaperInfo;
+
+WallpaperInfo *scanWallpapers(int *count);
+
+#endif
diff --git a/src/common/monitorScanner.c b/src/common/monitorScanner.c
new file mode 100644
index 0000000..dd39d73
--- /dev/null
+++ b/src/common/monitorScanner.c
@@ -0,0 +1,80 @@
+#include
+#include
+
+#include "../common.h"
+
+#ifdef __WIN32
+#include
+#else
+#include
+#include
+#endif
+
+#ifdef __WIN32
+int monitorEnumIndex = 0;
+
+BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
+{
+ MONITORINFO info;
+ info.cbSize = sizeof(MONITORINFO);
+
+ GetMonitorInfo(monitor, &info);
+
+ Monitor *m = (Monitor *)param;
+
+ snprintf(
+ m[monitorEnumIndex].name,
+ MONITOR_NAME_MAX,
+ "Monitor %d%s",
+ monitorEnumIndex + 1,
+ info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : ""
+ );
+ m[monitorEnumIndex].bounds.x = info.rcWork.left;
+ m[monitorEnumIndex].bounds.y = info.rcWork.top;
+ m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
+ m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
+ m[monitorEnumIndex].config.set = 0;
+
+ monitorEnumIndex++;
+ return TRUE;
+}
+#endif
+
+Monitor *scanMonitors(int *count)
+{
+ int monitorCount;
+ Monitor *m = NULL;
+
+#ifdef __WIN32
+ monitorCount = GetSystemMetrics(SM_CMONITORS);
+ m = malloc(sizeof(Monitor) * monitorCount);
+
+ monitorEnumIndex = 0;
+ EnumDisplayMonitors(NULL, NULL, &monitorenumproc, (LPARAM)m);
+
+#else
+ Display *display = XOpenDisplay((getenv("DISPLAY")));
+ Window wnd = DefaultRootWindow(display);
+ XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
+
+ m = malloc(sizeof(Monitor) * monitorCount);
+
+ int i = 0;
+ while (i < monitorCount)
+ {
+ snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
+ m[i].bounds.x = info->x;
+ m[i].bounds.y = info->y;
+ m[i].bounds.w = info->width;
+ m[i].bounds.h = info->height;
+ m[i].config.set = 0;
+
+ info++;
+ i++;
+ }
+
+ *count = monitorCount;
+
+#endif
+ return m;
+}
diff --git a/src/common/wallpaperScanner.c b/src/common/wallpaperScanner.c
new file mode 100644
index 0000000..2b835a2
--- /dev/null
+++ b/src/common/wallpaperScanner.c
@@ -0,0 +1,47 @@
+#include
+#include
+
+#include "../common.h"
+
+#define SYSTEM_WALLPAPERS_PATH "/usr/local/share/lwp/wallpapers"
+
+WallpaperInfo *scanWallpapers(int *count)
+{
+ *count = 0;
+
+ char userWlpPath[PATH_MAX];
+
+ sprintf(userWlpPath, "%s/.config/lwp/wallpapers", g_get_home_dir());
+
+ GDir *dir;
+ GError *error;
+ const gchar *filename;
+
+ dir = g_dir_open(SYSTEM_WALLPAPERS_PATH, 0, &error);
+ while ((g_dir_read_name(dir))) (*count)++;
+ dir = g_dir_open(userWlpPath, 0, &error);
+ while ((g_dir_read_name(dir))) (*count)++;
+
+ WallpaperInfo *list = malloc(sizeof(WallpaperInfo) * (*count));
+ WallpaperInfo *ptr = list;
+
+ dir = g_dir_open(SYSTEM_WALLPAPERS_PATH, 0, &error);
+ while ((filename = g_dir_read_name(dir)))
+ {
+ sprintf(ptr->name, "%s", filename);
+ sprintf(ptr->dirPath, "%s/%s", SYSTEM_WALLPAPERS_PATH, filename);
+ ptr->isDefault = 1;
+ ptr++;
+ }
+
+ dir = g_dir_open(userWlpPath, 0, &error);
+ while ((filename = g_dir_read_name(dir)))
+ {
+ sprintf(ptr->name, "%s", filename);
+ sprintf(ptr->dirPath, "%s/%s", SYSTEM_WALLPAPERS_PATH, filename);
+ ptr->isDefault = 0;
+ ptr++;
+ }
+
+ return list;
+}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8722b68..002f0c5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,9 +1,10 @@
set(_SOURCE_FILES
main.c
- windowHandlers.c
- monitorScanner.c
- wlp.c
- )
+ windowHandlers.c
+ wlp.c
+ ../common/wallpaperScanner.c
+ ../common/monitorScanner.c
+ )
# Windows resource file
if(_UNAME STREQUAL "WIN32")
diff --git a/src/core/main.c b/src/core/main.c
index 39e3ef8..843af0a 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -11,11 +11,12 @@
GtkApplication *app = NULL;
GtkBuilder *builder = NULL;
-GtkWidget *mainWnd = NULL;
-GtkWidget *exitDialog = NULL;
-GtkWidget *wallpaperMgrWnd = NULL;
-GtkWidget *monitorWnd = NULL;
-GtkWidget *monitorListBox = NULL;
+GtkWidget *mainWnd = NULL;
+GtkWidget *exitDialog = NULL;
+GtkWidget *wallpaperMgrWnd = NULL;
+GtkWidget *monitorWnd = NULL;
+GtkWidget *monitorListBox = NULL;
+GtkWidget *wallpaperListBox = NULL;
static void reloadMonitorListBox()
{
@@ -35,7 +36,7 @@ static void reloadMonitorListBox()
monitors = scanMonitors(&monitorsCount);
- for (int i = 0; i < 1; i++)
+ for (int i = 0; i < monitorsCount; i++)
{
GtkWidget *label = gtk_label_new(monitors[i].name);
GtkWidget *row = gtk_list_box_row_new();
@@ -62,6 +63,8 @@ static void activate(GtkApplication *app, gpointer userdata)
wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
monitorWnd = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow");
monitorListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_MonitorListBox");
+ wallpaperListBox =
+ (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow_WallpaperListBox");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
diff --git a/src/core/main.h b/src/core/main.h
index d4b6317..1216a32 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -3,29 +3,7 @@
#include
-#define MONITOR_NAME_MAX 100
-
-typedef struct
-{
- int x;
- int y;
- int w;
- int h;
-} Bounds;
-
-typedef struct
-{
- int set;
- char wlpPath[PATH_MAX];
- Bounds wlpBounds;
-} MonitorConfig;
-
-typedef struct
-{
- char name[MONITOR_NAME_MAX];
- Bounds bounds;
- MonitorConfig config;
-} Monitor;
+#include "../common.h"
extern GtkApplication *app;
@@ -33,10 +11,9 @@ extern GtkWidget *mainWnd;
extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
extern GtkWidget *monitorWnd;
+extern GtkWidget *wallpaperListBox;
void runWlp();
void killWlp();
-Monitor *scanMonitors(int *count);
-
#endif
diff --git a/src/core/monitorScanner.c b/src/core/monitorScanner.c
deleted file mode 100644
index 0745bf7..0000000
--- a/src/core/monitorScanner.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include "main.h"
-
-#include
-#include
-
-#ifdef __WIN32
-#include
-#else
-#include
-#include
-#endif
-
-#ifdef __WIN32
-int monitorEnumIndex = 0;
-
-BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
-{
- MONITORINFO info;
- info.cbSize = sizeof(MONITORINFO);
-
- GetMonitorInfo(monitor, &info);
-
- Monitor *m = (Monitor*)param;
-
- snprintf(m[monitorEnumIndex].name, MONITOR_NAME_MAX, "Monitor %d%s", monitorEnumIndex + 1, info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : "");
- m[monitorEnumIndex].bounds.x = info.rcWork.left;
- m[monitorEnumIndex].bounds.y = info.rcWork.top;
- m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
- m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
- m[monitorEnumIndex].config.set = 0;
-
- monitorEnumIndex++;
- return TRUE;
-}
-#endif
-
-Monitor* scanMonitors(int *count)
-{
- int monitorCount;
- Monitor *m = NULL;
-
-#ifdef __WIN32
- monitorCount = GetSystemMetrics(SM_CMONITORS);
- m = malloc(sizeof(Monitor) * monitorCount);
-
- monitorEnumIndex = 0;
- EnumDisplayMonitors(NULL, NULL, &monitorenumproc, (LPARAM)m);
-
-#else
- Display *display = XOpenDisplay((getenv("DISPLAY")));
- Window wnd = DefaultRootWindow(display);
- XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
-
- m = malloc(sizeof(Monitor) * monitorCount);
-
- int i = 0;
- while (i < monitorCount)
- {
- snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
- m[i].bounds.x = info->x;
- m[i].bounds.y = info->y;
- m[i].bounds.w = info->width;
- m[i].bounds.h = info->height;
- m[i].config.set = 0;
-
- info++;
- i++;
- }
-
- *count = monitorCount;
-
-#endif
- return m;
-}
\ No newline at end of file
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 9a3233f..5fba3d7 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -29,4 +29,24 @@ G_MODULE_EXPORT void MainWindowClose() { gtk_widget_set_visible(mainWnd, 0); }
G_MODULE_EXPORT void WallpaperManagerWindowClose() { gtk_widget_set_visible(wallpaperMgrWnd, 0); }
+G_MODULE_EXPORT void WallpaperManagerWindowShow()
+{
+ int wlpCount;
+ WallpaperInfo *wlpList = scanWallpapers(&wlpCount);
+
+ for (int i = 0; i < wlpCount; i++)
+ {
+ GtkWidget *label = gtk_label_new(wlpList[i].name);
+ GtkWidget *row = gtk_list_box_row_new();
+ gtk_container_add(GTK_CONTAINER(row), label);
+
+ gtk_list_box_insert(GTK_LIST_BOX(wallpaperListBox), row, 0);
+ gtk_widget_show_all(row);
+ }
+
+ free(wlpList);
+}
+
+// Monitor Window handlers
+
G_MODULE_EXPORT void MonitorWindowClose() { gtk_widget_set_visible(monitorWnd, 0); }
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 5c7c2f3..4bff1bc 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -285,6 +285,7 @@
False
+
True
@@ -308,7 +309,7 @@
-
+
True
False
From 9a917a7d393f13ba745b7a8f2ae69d7c0875ace8 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Mon, 15 Jan 2024 20:47:20 +0000
Subject: [PATCH 14/36] Monitor config window
---
src/core/main.c | 23 ++-
src/core/main.h | 5 +
src/core/windowHandlers.c | 27 ++++
src/window_templates/main.glade | 238 ++++++++++++++++++++++++++++++--
4 files changed, 275 insertions(+), 18 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 843af0a..233e179 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -11,12 +11,17 @@
GtkApplication *app = NULL;
GtkBuilder *builder = NULL;
-GtkWidget *mainWnd = NULL;
-GtkWidget *exitDialog = NULL;
-GtkWidget *wallpaperMgrWnd = NULL;
-GtkWidget *monitorWnd = NULL;
-GtkWidget *monitorListBox = NULL;
-GtkWidget *wallpaperListBox = NULL;
+GtkWidget *mainWnd = NULL;
+GtkWidget *exitDialog = NULL;
+GtkWidget *wallpaperMgrWnd = NULL;
+GtkWidget *monitorWnd = NULL;
+GtkWidget *monitorListBox = NULL;
+GtkWidget *wallpaperListBox = NULL;
+GtkWidget *wallpaperComboBox = NULL;
+GtkWidget *xPosSpinBtn = NULL;
+GtkWidget *yPosSpinBtn = NULL;
+GtkWidget *widthSpinBtn = NULL;
+GtkWidget *heightSpinBtn = NULL;
static void reloadMonitorListBox()
{
@@ -65,6 +70,12 @@ static void activate(GtkApplication *app, gpointer userdata)
monitorListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_MonitorListBox");
wallpaperListBox =
(GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow_WallpaperListBox");
+ wallpaperComboBox =
+ (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WallpaperComboBox");
+ xPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_XPosSpinBtn");
+ yPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_YPosSpinBtn");
+ widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WidthSpinBtn");
+ widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_HeightSpinBtn");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
diff --git a/src/core/main.h b/src/core/main.h
index 1216a32..ccf6181 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -12,6 +12,11 @@ extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
extern GtkWidget *monitorWnd;
extern GtkWidget *wallpaperListBox;
+extern GtkWidget *wallpaperComboBox;
+extern GtkWidget *xPosSpinBtn;
+extern GtkWidget *yPosSpinBtn;
+extern GtkWidget *widthSpinBtn;
+extern GtkWidget *heightSpinBtn;
void runWlp();
void killWlp();
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 5fba3d7..eeaf615 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -50,3 +50,30 @@ G_MODULE_EXPORT void WallpaperManagerWindowShow()
// Monitor Window handlers
G_MODULE_EXPORT void MonitorWindowClose() { gtk_widget_set_visible(monitorWnd, 0); }
+G_MODULE_EXPORT void MonitorWindowShow()
+{
+ int wlpCount;
+ WallpaperInfo *wlpList = scanWallpapers(&wlpCount);
+
+ for (int i = 0; i < wlpCount; i++)
+ {
+ gtk_combo_box_text_insert(
+ GTK_COMBO_BOX_TEXT(wallpaperComboBox), 0, wlpList[i].dirPath, wlpList[i].name
+ );
+ }
+
+ free(wlpList);
+}
+
+G_MODULE_EXPORT void MonitorWindow_ApplyBtnClick()
+{
+ MonitorConfig mc;
+ strcpy(mc.wlpPath, gtk_combo_box_get_active_id(GTK_COMBO_BOX(wallpaperComboBox)));
+ mc.wlpBounds.x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(xPosSpinBtn));
+ mc.wlpBounds.y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(yPosSpinBtn));
+ mc.wlpBounds.w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widthSpinBtn));
+ mc.wlpBounds.h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(heightSpinBtn));
+
+ killWlp();
+ runWlp();
+}
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 4bff1bc..af1d59e 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -67,6 +67,11 @@
+
+ 10000
+ 1
+ 10
+
False
False
@@ -265,27 +270,106 @@
-
+
False
-
+
+
True
False
vertical
-
+
+ True
+ False
+ 10
+ 10
+ Manage wallpapers
+
+
+
+
+
+ False
+ True
+ 0
+
-
+
+ True
+ False
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ center
+
+
+ Add
+ True
+ True
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ Remove
+ True
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 2
+
-
+
+ 10000
+ 1
+ 10
+
+
+ -10000
+ 10000
+ 1
+ 10
+
+
+ -10000
+ 10000
+ 1
+ 10
+
+
False
-
-
+
+
True
@@ -297,7 +381,8 @@
False
10
10
- Manage wallpapers
+ Monitor name
+ center
@@ -309,9 +394,136 @@
-
+
+
True
False
+ 20
+ 20
+ 15
+ True
+
+
+ True
+ False
+
+
+ 1
+ 0
+ 3
+
+
+
+
+ True
+ False
+ Wallpaper
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ X position
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Y position
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ Height
+
+
+ 2
+ 2
+
+
+
+
+ True
+ False
+ Width
+
+
+ 2
+ 1
+
+
+
+
+ True
+ True
+ 6
+ 1
+ number
+ XPosAdjustment
+
+
+ 1
+ 1
+
+
+
+
+ True
+ True
+ 6
+ 1
+ number
+ WidthAdjustment
+
+
+ 3
+ 1
+
+
+
+
+ True
+ True
+ 6
+ 1
+ number
+ HeightAdjustment
+
+
+ 3
+ 2
+
+
+
+
+ True
+ True
+ 6
+ 1
+ number
+ YPosAdjustment
+
+
+ 1
+ 2
+
+
False
@@ -324,12 +536,14 @@
True
False
center
+ 20
-
- Add
+
+ Apply
True
True
True
+
False
@@ -339,7 +553,7 @@
- Remove
+ Exit
True
True
True
From d6a287311814b385a5b7514bc86144543954ba0f Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Mon, 15 Jan 2024 21:17:12 +0000
Subject: [PATCH 15/36] Saving basic monitor config
---
src/common.h | 2 ++
src/common/config.c | 32 ++++++++++++++++++++++++++++++++
src/core/CMakeLists.txt | 8 +++++++-
src/core/main.c | 8 ++++----
src/core/windowHandlers.c | 2 ++
5 files changed, 47 insertions(+), 5 deletions(-)
create mode 100644 src/common/config.c
diff --git a/src/common.h b/src/common.h
index dbce32b..47c9550 100644
--- a/src/common.h
+++ b/src/common.h
@@ -45,4 +45,6 @@ typedef struct
WallpaperInfo *scanWallpapers(int *count);
+void saveMonitorConfig(MonitorConfig *mc);
+
#endif
diff --git a/src/common/config.c b/src/common/config.c
new file mode 100644
index 0000000..18c8764
--- /dev/null
+++ b/src/common/config.c
@@ -0,0 +1,32 @@
+#include
+
+#include "../common.h"
+
+void saveMonitorConfig(MonitorConfig *mc)
+{
+ config_t cfg;
+ config_setting_t *root, *setting;
+
+ config_init(&cfg);
+ root = config_root_setting(&cfg);
+
+ setting = config_setting_add(root, "wlpPath", CONFIG_TYPE_STRING);
+ config_setting_set_string(setting, mc->wlpPath);
+
+ setting = config_setting_add(root, "x", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, mc->wlpBounds.x);
+ setting = config_setting_add(root, "y", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, mc->wlpBounds.y);
+ setting = config_setting_add(root, "w", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, mc->wlpBounds.w);
+ setting = config_setting_add(root, "h", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, mc->wlpBounds.h);
+
+ if (!config_write_file(&cfg, "test.cfg"))
+ {
+ fprintf(stderr, "Error while writing file.\n");
+ config_destroy(&cfg);
+ }
+
+ config_destroy(&cfg);
+}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 002f0c5..dd4556e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -4,6 +4,7 @@ set(_SOURCE_FILES
wlp.c
../common/wallpaperScanner.c
../common/monitorScanner.c
+ ../common/config.c
)
# Windows resource file
@@ -20,6 +21,8 @@ if(_UNAME STREQUAL "WIN32")
list(APPEND _SOURCE_FILES "resource.rc")
endif()
+find_package (PkgConfig REQUIRED)
+
if (_UNAME STREQUAL "LINUX")
# X11 and Xrandr dependency
include(FindX11)
@@ -32,11 +35,14 @@ if (_UNAME STREQUAL "LINUX")
endif()
# GTK dependency
-find_package (PkgConfig REQUIRED)
pkg_check_modules (GTK3 REQUIRED gtk+-3.0)
list(APPEND _INCLUDE_DIRS ${GTK3_INCLUDE_DIRS})
list(APPEND _LIBS ${GTK3_LINK_LIBRARIES})
+# libconfig dependency
+pkg_check_modules (libconfig REQUIRED libconfig)
+list(APPEND _INCLUDE_DIRS ${libconfig_INCLUDE_DIRS})
+list(APPEND _LIBS ${libconfig_LINK_LIBRARIES})
# Main executable
if (_UNAME STREQUAL "DARWIN")
diff --git a/src/core/main.c b/src/core/main.c
index 233e179..b6bf496 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -72,10 +72,10 @@ static void activate(GtkApplication *app, gpointer userdata)
(GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow_WallpaperListBox");
wallpaperComboBox =
(GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WallpaperComboBox");
- xPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_XPosSpinBtn");
- yPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_YPosSpinBtn");
- widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WidthSpinBtn");
- widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_HeightSpinBtn");
+ xPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_XPosSpinBtn");
+ yPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_YPosSpinBtn");
+ widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WidthSpinBtn");
+ heightSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_HeightSpinBtn");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index eeaf615..23be66d 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -74,6 +74,8 @@ G_MODULE_EXPORT void MonitorWindow_ApplyBtnClick()
mc.wlpBounds.w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widthSpinBtn));
mc.wlpBounds.h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(heightSpinBtn));
+ saveMonitorConfig(&mc);
+
killWlp();
runWlp();
}
From 281805d6980a3d469786b71c0192337d037f4a4d Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Tue, 16 Jan 2024 00:21:55 +0000
Subject: [PATCH 16/36] Saving and loading monitor configuration
---
src/common.h | 9 ++++---
src/common/config.c | 46 ++++++++++++++++++++++++++++++---
src/common/monitorScanner.c | 8 +++---
src/core/main.c | 7 +++--
src/core/main.h | 2 ++
src/core/windowHandlers.c | 27 ++++++++++++++++---
src/window_templates/main.glade | 3 ++-
7 files changed, 84 insertions(+), 18 deletions(-)
diff --git a/src/common.h b/src/common.h
index 47c9550..2d127fa 100644
--- a/src/common.h
+++ b/src/common.h
@@ -23,7 +23,7 @@ typedef struct
typedef struct
{
int set;
- char wlpPath[PATH_MAX];
+ char wlpName[WALLPAPER_NAME_MAX];
Bounds wlpBounds;
} MonitorConfig;
@@ -32,9 +32,9 @@ typedef struct
char name[MONITOR_NAME_MAX];
Bounds bounds;
MonitorConfig config;
-} Monitor;
+} MonitorInfo;
-Monitor *scanMonitors(int *count);
+MonitorInfo *scanMonitors(int *count);
typedef struct
{
@@ -45,6 +45,7 @@ typedef struct
WallpaperInfo *scanWallpapers(int *count);
-void saveMonitorConfig(MonitorConfig *mc);
+void saveMonitorConfig(const char *name, MonitorConfig *mc);
+int loadMonitorConfig(const char *name, MonitorConfig *mc);
#endif
diff --git a/src/common/config.c b/src/common/config.c
index 18c8764..6cac664 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -1,8 +1,14 @@
+#include
#include
#include "../common.h"
-void saveMonitorConfig(MonitorConfig *mc)
+void getMonitorConfigPath(const char *name, char *path)
+{
+ sprintf(path, "%s/.config/lwp/monitors/%s.cfg", g_get_home_dir(), name);
+}
+
+void saveMonitorConfig(const char *name, MonitorConfig *mc)
{
config_t cfg;
config_setting_t *root, *setting;
@@ -10,8 +16,8 @@ void saveMonitorConfig(MonitorConfig *mc)
config_init(&cfg);
root = config_root_setting(&cfg);
- setting = config_setting_add(root, "wlpPath", CONFIG_TYPE_STRING);
- config_setting_set_string(setting, mc->wlpPath);
+ setting = config_setting_add(root, "wlpName", CONFIG_TYPE_STRING);
+ config_setting_set_string(setting, mc->wlpName);
setting = config_setting_add(root, "x", CONFIG_TYPE_INT);
config_setting_set_int(setting, mc->wlpBounds.x);
@@ -22,7 +28,10 @@ void saveMonitorConfig(MonitorConfig *mc)
setting = config_setting_add(root, "h", CONFIG_TYPE_INT);
config_setting_set_int(setting, mc->wlpBounds.h);
- if (!config_write_file(&cfg, "test.cfg"))
+ char path[PATH_MAX];
+ getMonitorConfigPath(name, path);
+
+ if (!config_write_file(&cfg, path))
{
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
@@ -30,3 +39,32 @@ void saveMonitorConfig(MonitorConfig *mc)
config_destroy(&cfg);
}
+
+int loadMonitorConfig(const char *name, MonitorConfig *mc)
+{
+ config_t cfg;
+ config_setting_t *root, *setting;
+
+ char path[PATH_MAX];
+ getMonitorConfigPath(name, path);
+
+ config_init(&cfg);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ root = config_root_setting(&cfg);
+
+ setting = config_setting_get_member(root, "wlpName");
+ strcpy(mc->wlpName, config_setting_get_string(setting));
+
+ setting = config_setting_get_member(root, "x");
+ mc->wlpBounds.x = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "y");
+ mc->wlpBounds.y = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "w");
+ mc->wlpBounds.w = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "h");
+ mc->wlpBounds.h = config_setting_get_int(setting);
+
+ config_destroy(&cfg);
+
+ return 1;
+}
diff --git a/src/common/monitorScanner.c b/src/common/monitorScanner.c
index dd39d73..0e562f3 100644
--- a/src/common/monitorScanner.c
+++ b/src/common/monitorScanner.c
@@ -40,10 +40,10 @@ BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
}
#endif
-Monitor *scanMonitors(int *count)
+MonitorInfo *scanMonitors(int *count)
{
- int monitorCount;
- Monitor *m = NULL;
+ int monitorCount;
+ MonitorInfo *m = NULL;
#ifdef __WIN32
monitorCount = GetSystemMetrics(SM_CMONITORS);
@@ -57,7 +57,7 @@ Monitor *scanMonitors(int *count)
Window wnd = DefaultRootWindow(display);
XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
- m = malloc(sizeof(Monitor) * monitorCount);
+ m = malloc(sizeof(MonitorInfo) * monitorCount);
int i = 0;
while (i < monitorCount)
diff --git a/src/core/main.c b/src/core/main.c
index b6bf496..079cfa4 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -22,6 +22,7 @@ GtkWidget *xPosSpinBtn = NULL;
GtkWidget *yPosSpinBtn = NULL;
GtkWidget *widthSpinBtn = NULL;
GtkWidget *heightSpinBtn = NULL;
+GtkWidget *monitorNameLabel = NULL;
static void reloadMonitorListBox()
{
@@ -36,8 +37,8 @@ static void reloadMonitorListBox()
g_list_free(rows);
- int monitorsCount;
- Monitor *monitors;
+ int monitorsCount;
+ MonitorInfo *monitors;
monitors = scanMonitors(&monitorsCount);
@@ -76,6 +77,8 @@ static void activate(GtkApplication *app, gpointer userdata)
yPosSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_YPosSpinBtn");
widthSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_WidthSpinBtn");
heightSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_HeightSpinBtn");
+ monitorNameLabel =
+ (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_MonitorNameLabel");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
diff --git a/src/core/main.h b/src/core/main.h
index ccf6181..add9ac0 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -11,12 +11,14 @@ extern GtkWidget *mainWnd;
extern GtkWidget *exitDialog;
extern GtkWidget *wallpaperMgrWnd;
extern GtkWidget *monitorWnd;
+extern GtkWidget *monitorListBox;
extern GtkWidget *wallpaperListBox;
extern GtkWidget *wallpaperComboBox;
extern GtkWidget *xPosSpinBtn;
extern GtkWidget *yPosSpinBtn;
extern GtkWidget *widthSpinBtn;
extern GtkWidget *heightSpinBtn;
+extern GtkWidget *monitorNameLabel;
void runWlp();
void killWlp();
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 23be66d..82aa588 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -52,29 +52,50 @@ G_MODULE_EXPORT void WallpaperManagerWindowShow()
G_MODULE_EXPORT void MonitorWindowClose() { gtk_widget_set_visible(monitorWnd, 0); }
G_MODULE_EXPORT void MonitorWindowShow()
{
+ // Load wallpaper list
int wlpCount;
WallpaperInfo *wlpList = scanWallpapers(&wlpCount);
for (int i = 0; i < wlpCount; i++)
{
gtk_combo_box_text_insert(
- GTK_COMBO_BOX_TEXT(wallpaperComboBox), 0, wlpList[i].dirPath, wlpList[i].name
+ GTK_COMBO_BOX_TEXT(wallpaperComboBox), 0, wlpList[i].name, wlpList[i].name
);
}
+ gtk_combo_box_set_active(GTK_COMBO_BOX(wallpaperComboBox), 0);
free(wlpList);
+
+ // Find selected monitor name
+ GtkListBoxRow *listBoxRow = gtk_list_box_get_selected_row(GTK_LIST_BOX(monitorListBox));
+ GList *children = gtk_container_get_children(GTK_CONTAINER(listBoxRow));
+ const char *monitorName = gtk_label_get_label(GTK_LABEL(children->data));
+ gtk_label_set_text(GTK_LABEL(monitorNameLabel), monitorName);
+ g_list_free(children);
+
+ // Read configuration from config file
+ MonitorConfig mc;
+ if (loadMonitorConfig(monitorName, &mc))
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(xPosSpinBtn), (gdouble)mc.wlpBounds.x);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(yPosSpinBtn), (gdouble)mc.wlpBounds.y);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widthSpinBtn), (gdouble)mc.wlpBounds.w);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(heightSpinBtn), (gdouble)mc.wlpBounds.h);
+
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(wallpaperComboBox), mc.wlpName);
+ }
}
G_MODULE_EXPORT void MonitorWindow_ApplyBtnClick()
{
MonitorConfig mc;
- strcpy(mc.wlpPath, gtk_combo_box_get_active_id(GTK_COMBO_BOX(wallpaperComboBox)));
+ strcpy(mc.wlpName, gtk_combo_box_get_active_id(GTK_COMBO_BOX(wallpaperComboBox)));
mc.wlpBounds.x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(xPosSpinBtn));
mc.wlpBounds.y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(yPosSpinBtn));
mc.wlpBounds.w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widthSpinBtn));
mc.wlpBounds.h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(heightSpinBtn));
- saveMonitorConfig(&mc);
+ saveMonitorConfig(gtk_label_get_text(GTK_LABEL(monitorNameLabel)), &mc);
killWlp();
runWlp();
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index af1d59e..b52a7e5 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -376,7 +376,7 @@
False
vertical
-
+
True
False
10
@@ -406,6 +406,7 @@
True
False
+ 0
1
From 94a0ab040ff4e8eca4d90caacf56d6804cc4edca Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Wed, 31 Jan 2024 12:59:01 +0000
Subject: [PATCH 17/36] Loading configuration from wallpaper process
---
default.cfg | 41 +---
src/common.h | 37 +++-
src/common/config.c | 77 ++++++++
src/core/CMakeLists.txt | 2 +-
src/core/wlp.c | 62 +++---
src/wlp/CMakeLists.txt | 34 +++-
src/wlp/debug.c | 21 +-
src/wlp/main.c | 176 ++++++++++++++---
src/wlp/main.h | 41 ++--
src/wlp/wallpaper.c | 242 +++++++++++++-----------
src/wlp/wallpaper.h | 4 -
src/wlp/window.c | 104 +++++++---
src/wlp/window.h | 4 +-
wallpapers/default-fullhd/wallpaper.cfg | 19 +-
14 files changed, 566 insertions(+), 298 deletions(-)
diff --git a/default.cfg b/default.cfg
index 1a03de4..ab24da3 100644
--- a/default.cfg
+++ b/default.cfg
@@ -1,39 +1,2 @@
-# ██╗ ██╗ ██╗██████╗
-# ██║ ██║ ██║██╔══██╗
-# ██║ ██║ █╗ ██║██████╔╝
-# ██║ ██║███╗██║██╔═══╝
-# ███████╗╚███╔███╔╝██║
-# ╚══════╝ ╚══╝╚══╝ ╚═╝
-
-# If You are using a compositor, or lwp window deosn't show,
-# try setting this to 1
-reload_rootwindow=0
-
-# Smooth movement
-# Increasing this value will make the wallpaper layers move faster
-smooth=8.0
-
-# Monitors count
-monitors=1
-
-# Monitor position
-monitor1_x=0
-monitor1_y=0
-
-# Monitor resolution
-monitor1_w=1920
-monitor1_h=1080
-
-# Absolute path to the wallpaper directory
-monitor1_wallpaper=/usr/local/share/lwp/wallpapers/default-fullhd
-
-# Wallpaper size and position relative to Your monitor
-# Wallpaper resolution ratio should be the same as in original image
-monitor1_wallpaper_x=0
-monitor1_wallpaper_y=0
-monitor1_wallpaper_w=1920
-monitor1_wallpaper_h=1080
-
-# How many times per second should the wallpaper render
-# (imprecise, but accurate enough)
-target_fps=60
+draw_on_rootwindow= 0;
+target_fps = 60;
diff --git a/src/common.h b/src/common.h
index 2d127fa..ac50ff5 100644
--- a/src/common.h
+++ b/src/common.h
@@ -20,6 +20,29 @@ typedef struct
int h;
} Bounds;
+typedef struct
+{
+ float sensitivityX;
+ float sensitivityY;
+} LayerConfig;
+
+typedef struct
+{
+ int set;
+ int repeatX;
+ int repeatY;
+ int layersCount;
+ LayerConfig *layerConfigs;
+} WallpaperConfig;
+
+typedef struct
+{
+ char name[WALLPAPER_NAME_MAX];
+ char dirPath[PATH_MAX];
+ int isDefault;
+ WallpaperConfig config;
+} WallpaperInfo;
+
typedef struct
{
int set;
@@ -34,18 +57,20 @@ typedef struct
MonitorConfig config;
} MonitorInfo;
-MonitorInfo *scanMonitors(int *count);
-
typedef struct
{
- char name[WALLPAPER_NAME_MAX];
- char dirPath[PATH_MAX];
- int isDefault;
-} WallpaperInfo;
+ int drawOnRootWindow;
+ int targetFps;
+} AppConfig;
+MonitorInfo *scanMonitors(int *count);
WallpaperInfo *scanWallpapers(int *count);
void saveMonitorConfig(const char *name, MonitorConfig *mc);
int loadMonitorConfig(const char *name, MonitorConfig *mc);
+int loadAppConfig(AppConfig *ac);
+
+int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc);
+
#endif
diff --git a/src/common/config.c b/src/common/config.c
index 6cac664..9530b91 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -1,13 +1,25 @@
#include
#include
+#include
#include "../common.h"
+#define CONFIG_DEFAULT 0
+#define CONFIG_USER 1
+
void getMonitorConfigPath(const char *name, char *path)
{
sprintf(path, "%s/.config/lwp/monitors/%s.cfg", g_get_home_dir(), name);
}
+void getAppConfigPath(char *path, int type)
+{
+ if (type == CONFIG_DEFAULT)
+ sprintf(path, "/etc/lwp.cfg");
+ else
+ sprintf(path, "%s/.config/lwp/lwp.cfg", g_get_home_dir());
+}
+
void saveMonitorConfig(const char *name, MonitorConfig *mc)
{
config_t cfg;
@@ -68,3 +80,68 @@ int loadMonitorConfig(const char *name, MonitorConfig *mc)
return 1;
}
+
+int loadAppConfig(AppConfig *ac)
+{
+ config_t cfg;
+ config_setting_t *root, *setting;
+
+ char path[PATH_MAX];
+ getAppConfigPath(path, CONFIG_USER);
+
+ config_init(&cfg);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ {
+ getAppConfigPath(path, CONFIG_DEFAULT);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ }
+ root = config_root_setting(&cfg);
+
+ setting = config_setting_get_member(root, "draw_on_rootwindow");
+ ac->drawOnRootWindow = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "target_fps");
+ ac->targetFps = config_setting_get_int(setting);
+
+ config_destroy(&cfg);
+
+ return 1;
+}
+
+int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc)
+{
+ char path[PATH_MAX];
+ sprintf(path, "%s/wallpaper.cfg", dirName);
+
+ config_t cfg;
+ config_setting_t *root, *setting;
+
+ config_init(&cfg);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ root = config_root_setting(&cfg);
+
+ setting = config_setting_get_member(root, "count");
+ wc->layersCount = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_x");
+ wc->repeatX = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_y");
+ wc->repeatY = config_setting_get_int(setting);
+
+ wc->layerConfigs = malloc(wc->layersCount * sizeof(LayerConfig));
+
+ setting = config_setting_get_member(root, "movement_x");
+ float movX = config_setting_get_float(setting);
+ setting = config_setting_get_member(root, "movement_y");
+ float movY = config_setting_get_float(setting);
+
+ for (int i = 0; i < wc->layersCount; i++)
+ {
+ LayerConfig *lc = wc->layerConfigs + i;
+
+ lc->sensitivityX = movX * i;
+ lc->sensitivityY = movY * i;
+ }
+
+ config_destroy(&cfg);
+
+ return 1;
+}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index dd4556e..1403137 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -2,9 +2,9 @@ set(_SOURCE_FILES
main.c
windowHandlers.c
wlp.c
- ../common/wallpaperScanner.c
../common/monitorScanner.c
../common/config.c
+ ../common/wallpaperScanner.c
)
# Windows resource file
diff --git a/src/core/wlp.c b/src/core/wlp.c
index 0e6b032..a51aac9 100644
--- a/src/core/wlp.c
+++ b/src/core/wlp.c
@@ -1,8 +1,10 @@
#include "main.h"
#ifdef __WIN32
-#include
#include
+#include
+#else
+#include
#endif
#ifdef __WIN32
@@ -15,9 +17,13 @@ static int wlpPid = 0;
void killWlp()
{
#ifdef __WIN32
- TerminateProcess(hWlpProcess, 0);
+ TerminateProcess(hWlpProcess, 0);
#else
- if (wlpPid != 0) kill(wlpPid, SIGINT);
+ if (wlpPid != 0)
+ {
+ kill(wlpPid, SIGINT);
+ waitpid(wlpPid, NULL, 0);
+ }
if (wlpProcess != NULL) pclose(wlpProcess);
wlpPid = 0;
@@ -28,40 +34,28 @@ void killWlp()
void runWlp()
{
#ifdef __WIN32
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
- ZeroMemory(&si, sizeof(si));
- ZeroMemory(&pi, sizeof(pi));
- si.cb = sizeof(si);
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ si.cb = sizeof(si);
- TCHAR path[MAX_PATH];
- GetModuleFileName(NULL, path, MAX_PATH);
- path[_tcslen(path)-4] = '\0';
- _tcscat(path, TEXT("wlp.exe"));
- printf("%s\n", path);
+ TCHAR path[MAX_PATH];
+ GetModuleFileName(NULL, path, MAX_PATH);
+ path[_tcslen(path) - 4] = '\0';
+ _tcscat(path, TEXT("wlp.exe"));
+ printf("%s\n", path);
- if(CreateProcess(
- NULL,
- path,
- NULL,
- NULL,
- FALSE,
- 0,
- NULL,
- NULL,
- &si,
- &pi
- ))
- hWlpProcess = pi.hProcess;
- else
- printf("Failed to start a wallpaper subprocess");
+ if (CreateProcess(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+ hWlpProcess = pi.hProcess;
+ else
+ printf("Failed to start a wallpaper subprocess");
-
#else
- wlpProcess = popen("/home/cziken/Projects/lwp/build/src/wlp/lwpwlp", "r");
- char buff[10];
- fgets(buff, sizeof(buff) - 1, wlpProcess);
- wlpPid = atoi(buff);
+ wlpProcess = popen("/usr/local/bin/lwpwlp", "r");
+ char buff[10];
+ fgets(buff, sizeof(buff) - 1, wlpProcess);
+ wlpPid = atoi(buff);
#endif
-}
\ No newline at end of file
+}
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 7ba99e0..0ddfdae 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -3,17 +3,41 @@ if(SDL2_RUNTIME_DIR)
endif()
set(_SOURCE_FILES
+ ../common/monitorScanner.c
+ ../common/config.c
+ ../common/wallpaperScanner.c
main.c
- debug.c
- parser.c
+ debug.c
wallpaper.c
window.c
- )
+ )
+
+# GLIB dependency
+find_package(PkgConfig REQUIRED)
+pkg_search_module(GLIB REQUIRED glib-2.0)
+set(_INCLUDE_DIRS ${GLIB_INCLUDE_DIRS})
+set(_LIBS ${GLIB_LDFLAGS})
+
+if (_UNAME STREQUAL "LINUX")
+ # X11 and Xrandr dependency
+ include(FindX11)
+
+ list(APPEND _INCLUDE_DIRS ${X11_INCLUDE_DIR})
+ list(APPEND _LIBS ${X11_LIBRARIES})
+
+ list(APPEND _INCLUDE_DIRS ${X11_Xrandr_INCLUDE_PATH})
+ list(APPEND _LIBS ${X11_Xrandr_LIB})
+endif()
+
+# libconfig dependency
+pkg_check_modules (libconfig REQUIRED libconfig)
+list(APPEND _INCLUDE_DIRS ${libconfig_INCLUDE_DIRS})
+list(APPEND _LIBS ${libconfig_LINK_LIBRARIES})
# SDL2 dependency
find_package(SDL2 REQUIRED CONFIG)
-set(_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
-set(_LIBS ${SDL2_LIBRARIES})
+list(APPEND _INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
+list(APPEND _LIBS ${SDL2_LIBRARIES})
if (_UNAME STREQUAL "DARWIN")
# MacOSX framework dependencies
diff --git a/src/wlp/debug.c b/src/wlp/debug.c
index 2381d3d..f66e7ee 100644
--- a/src/wlp/debug.c
+++ b/src/wlp/debug.c
@@ -5,33 +5,32 @@
void lwpLog(int type, const char *str, ...)
{
- char *typePrefixCodes;
char *typePrefix;
+ FILE *file = fopen("/home/cziken/.config/lwp/log", "a");
+
switch (type)
{
case LOG_ERROR:
- typePrefixCodes = "\x1b[31m\x1b[1m";
- typePrefix = "ERROR";
+ typePrefix = "ERROR";
break;
case LOG_INFO:
- typePrefixCodes = "\x1b[34m\x1b[1m";
- typePrefix = "INFO";
+ typePrefix = "INFO";
break;
case LOG_WARNING:
- typePrefixCodes = "\x1b[33m\x1b[1m";
- typePrefix = "WARNING";
+ typePrefix = "WARNING";
break;
}
- printf("%s%s: \x1b[0m", typePrefixCodes, typePrefix);
+ fprintf(file, "%s: ", typePrefix);
va_list args;
va_start(args, str);
- vprintf(str, args);
+ vfprintf(file, str, args);
va_end(args);
- putchar('\n');
- fflush(stdout);
+ fprintf(file, "\n");
+
+ fclose(file);
}
diff --git a/src/wlp/main.c b/src/wlp/main.c
index d7b5842..5c11052 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -1,10 +1,8 @@
#include "main.h"
#include "debug.h"
-#include "parser.h"
#include "platform_guard.h"
#include "wallpaper.h"
-#include "window.h"
#ifdef __WIN32
static void initCmd()
@@ -26,7 +24,7 @@ static void initCmd()
// Set console title
SetConsoleTitle("Layered WallPaper");
}
-BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
+BOOLmonitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
{
int px = GetSystemMetrics(SM_XVIRTUALSCREEN);
int py = GetSystemMetrics(SM_YVIRTUALSCREEN);
@@ -47,34 +45,164 @@ BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
return TRUE;
}
+/*
static void scanMonitors()
{
lwpLog(LOG_INFO, "Scanning monitors...");
EnumDisplayMonitors(NULL, NULL, &monitorenumproc, NULL);
-}
+}*/
#endif
-static Config cfg;
+static App app;
static void atExit()
{
- freeConfig(&cfg);
-
- SDL_DestroyRenderer(cfg.renderer);
- SDL_DestroyWindow(cfg.window);
- SDL_Quit();
+ // freeConfig(&cfg);
+ /*
+ SDL_DestroyRenderer(app.renderer);
+ SDL_DestroyWindow(app.window);
+ SDL_Quit();*/
}
void exitSignalHandler(int s)
{
+ lwpLog(LOG_INFO, "Terminating...");
exit(0);
}
+void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpapersCount)
+{
+ MonitorInfo *mi = &m->info;
+
+ int foundWlp = 0;
+
+ for (int j = 0; j < wallpapersCount; j++)
+ {
+ if (strcmp(mi->config.wlpName, wallpapers[j].name) == 0)
+ {
+ memcpy(&m->wlp.info, wallpapers + j, sizeof(WallpaperInfo));
+
+ if (!loadWallpaperConfig(m->wlp.info.dirPath, &m->wlp.info.config))
+ {
+ m->wlp.info.config.set = 0;
+ lwpLog(LOG_WARNING, "Could not load the wallpaper config");
+ }
+ else
+ {
+ Wallpaper *wallpaper = &m->wlp;
+
+ lwpLog(LOG_INFO, "Initializing wallpaper %s...", wallpaper->info.name);
+ lwpLog(LOG_INFO, "Layers count: %d", wallpaper->info.config.layersCount);
+ lwpLog(
+ LOG_INFO,
+ "Repeat X Y: %d %d",
+ wallpaper->info.config.repeatX,
+ wallpaper->info.config.repeatY
+ );
+
+ m->tex = SDL_CreateTexture(
+ app->renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET,
+ mi->bounds.w,
+ mi->bounds.h
+ );
+ if (m->tex == NULL)
+ lwpLog(LOG_ERROR, "Failed creating a texture for the monitor: %s", SDL_GetError());
+
+ wallpaper->layers = malloc(sizeof(Layer) * wallpaper->info.config.layersCount);
+ wallpaper->tex = SDL_CreateTexture(
+ app->renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET,
+ mi->config.wlpBounds.w,
+ mi->config.wlpBounds.h
+ );
+ if (wallpaper->tex == NULL)
+ lwpLog(LOG_ERROR, "Failed creating a texture for the monitor: %s", SDL_GetError());
+
+ for (int l = 0; l < wallpaper->info.config.layersCount; l++)
+ {
+ char path[PATH_MAX];
+ snprintf(path, PATH_MAX, "%s/%d.bmp", wallpaper->info.dirPath, l + 1);
+
+ SDL_Surface *surf = SDL_LoadBMP(path);
+ if (!surf) lwpLog(LOG_ERROR, "File %s not found", path);
+
+ if (l == 0)
+ {
+ wallpaper->originalW = surf->w;
+ wallpaper->originalH = surf->h;
+ }
+
+ wallpaper->layers[l].tex = SDL_CreateTextureFromSurface(app->renderer, surf);
+ if (wallpaper->tex == NULL)
+ lwpLog(LOG_ERROR, "Failed creating a texture for the layer %d: %s", l, SDL_GetError());
+
+ SDL_FreeSurface(surf);
+ }
+ }
+ foundWlp = 1;
+
+ break;
+ }
+ }
+ if (!foundWlp) lwpLog(LOG_WARNING, "Couldn't find the wallpaper. Ignoring...");
+}
+
+void initMonitors(App *app)
+{
+ MonitorInfo *monitors = scanMonitors(&app->monitorsCount);
+ app->monitors = malloc(sizeof(Monitor) * app->monitorsCount);
+
+ int wallpapersCount;
+ WallpaperInfo *wallpapers = scanWallpapers(&wallpapersCount);
+
+ lwpLog(LOG_INFO, "Scanner found %d monitor(s)", app->monitorsCount);
+
+ for (int i = 0; i < app->monitorsCount; i++)
+ {
+ memcpy(&app->monitors[i].info, monitors + i, sizeof(MonitorInfo));
+ app->monitors[i].tex = NULL;
+
+ MonitorInfo *mi = &app->monitors[i].info;
+
+ if (!loadMonitorConfig(mi->name, &mi->config))
+ {
+ lwpLog(LOG_WARNING, "Couldn't find config file for monitor %s. Ignoring...", mi->name);
+ mi->config.set = 0;
+ }
+ else
+ {
+ lwpLog(LOG_INFO, "Initializing monitor %d...", i);
+ lwpLog(LOG_INFO, "Wallpaper: %s", mi->config.wlpName);
+ lwpLog(
+ LOG_INFO, "Bounds: %d %d %dx%d", mi->bounds.x, mi->bounds.y, mi->bounds.w, mi->bounds.h
+ );
+ lwpLog(
+ LOG_INFO,
+ "Wallpaper destination bounds: %d %d %dx%d",
+ mi->config.wlpBounds.x,
+ mi->config.wlpBounds.y,
+ mi->config.wlpBounds.w,
+ mi->config.wlpBounds.h
+ );
+
+ initWallpaper(app, app->monitors + i, wallpapers, wallpapersCount);
+ }
+ }
+
+ free(wallpapers);
+ free(monitors);
+}
+
int main(int argc, char *argv[])
{
char pidStr[10];
sprintf(pidStr, "%d\0", getpid());
fputs(pidStr, stdout);
+ printf("\n");
+ fflush(stdout);
#ifdef __WIN32
signal(SIGTERM, exitSignalHandler);
@@ -88,27 +216,29 @@ int main(int argc, char *argv[])
if (argc == 2 && strcmp(argv[1], "/console") == 0) initCmd();
initTrayIcon();
- scanMonitors();
+ // scanMonitors();
#endif
- parseConfig(&cfg);
+ lwpLog(LOG_INFO, "Loading app config");
+ loadAppConfig(&app.config);
+ lwpLog(LOG_INFO, "Initializing SDL");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
- initWindow(&cfg);
+
+ lwpLog(LOG_INFO, "Initializing window");
+ initWindow(&app);
+
+ lwpLog(LOG_INFO, "Initializing monitors");
+ initMonitors(&app);
atexit(atExit);
- cfg.renderer =
- SDL_CreateRenderer(cfg.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- if (cfg.renderer == NULL)
- {
- lwpLog(LOG_ERROR, "%s", SDL_GetError());
- }
- runWallpaperLoop(&cfg);
+ lwpLog(LOG_INFO, "Starting wallpaper loop");
+ runWallpaperLoop(&app);
- #ifdef __WIN32
- removeTrayIcon();
- #endif
+#ifdef __WIN32
+ removeTrayIcon();
+#endif
return 0;
}
diff --git a/src/wlp/main.h b/src/wlp/main.h
index 71cb43b..e799f2c 100644
--- a/src/wlp/main.h
+++ b/src/wlp/main.h
@@ -14,11 +14,11 @@
#include
#include
#elif __DARWIN
-#include
-#include
#include
#include
#include
+#include
+#include
#include
#elif __LINUX
#include
@@ -28,40 +28,39 @@
#include
#endif
+#include "../common.h"
+
typedef struct
{
- float sensitivityX;
- float sensitivityY;
SDL_Texture *tex;
} Layer;
typedef struct
{
- char dirPath[PATH_MAX];
- int repeatX, repeatY;
- int layersCount;
- Layer *layers;
- int originalW, originalH;
- SDL_Texture *tex;
+ WallpaperInfo info;
+ int originalW;
+ int originalH;
+ SDL_Texture *tex;
+ Layer *layers;
} Wallpaper;
typedef struct
{
- int x, y, w, h;
- int wallpaperX, wallpaperY, wallpaperW, wallpaperH;
+ MonitorInfo info;
SDL_Texture *tex;
- Wallpaper wallpaper;
-} WallpaperDest;
+ Wallpaper wlp;
+} Monitor;
typedef struct
{
- int reloadRootWnd;
- int monitorsCount;
- float smooth;
- int targetFPS;
- WallpaperDest *monitors;
+ AppConfig config;
+ int monitorsCount;
+ Monitor *monitors;
SDL_Window *window;
SDL_Renderer *renderer;
-} Config;
+} App;
+
+void initWindow(App *app);
+void runWallpaperLoop(App *app);
-#endif // MAIN_H
+#endif // MAIN_H
diff --git a/src/wlp/wallpaper.c b/src/wlp/wallpaper.c
index edec74a..1136bce 100644
--- a/src/wlp/wallpaper.c
+++ b/src/wlp/wallpaper.c
@@ -5,9 +5,11 @@
#endif
#include "debug.h"
-#include "parser.h"
-
-static int appplyWallpaper(Config *cfg, WallpaperDest *monitor, Wallpaper *wallpaper, const char *dirPath)
+#include "main.h"
+/*
+static int appplyWallpaper(
+ App *app, MonitorInfo *monitor, Wallpaper *wallpaper, const char *dirPath
+)
{
char path[PATH_MAX];
@@ -40,27 +42,33 @@ static int appplyWallpaper(Config *cfg, WallpaperDest *monitor, Wallpaper *wallp
SDL_FreeSurface(surf);
}
- wallpaper->tex =
- SDL_CreateTexture(cfg->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
- monitor->wallpaperW, monitor->wallpaperH);
+ wallpaper->tex = SDL_CreateTexture(
+ cfg->renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_TARGET,
+ monitor->wallpaperW,
+ monitor->wallpaperH
+ );
- monitor->tex = SDL_CreateTexture(cfg->renderer, SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_TARGET, monitor->w, monitor->h);
+ monitor->tex = SDL_CreateTexture(
+ cfg->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, monitor->w, monitor->h
+ );
return 1;
}
-int applyWallpapers(Config *cfg)
+int initWallpapers(App *app)
{
- for (int m = 0; m < cfg->monitorsCount; m++)
- if (!appplyWallpaper(cfg, &cfg->monitors[m], &cfg->monitors[m].wallpaper,
- cfg->monitors[m].wallpaper.dirPath))
+ for (int m = 0; m < app->monitorsCount; m++)
+ if (!appplyWallpaper(
+ app, &cfg->monitors[m], &cfg->monitors[m].wallpaper, cfg->monitors[m].wallpaper.dirPath
+ ))
return 0;
return 1;
-}
-
-void freeMonitor(WallpaperDest *monitor)
+}*/
+/*
+void freeMonitor(MonitorInfo *monitor)
{
SDL_DestroyTexture(monitor->tex);
SDL_DestroyTexture(monitor->wallpaper.tex);
@@ -70,7 +78,7 @@ void freeMonitor(WallpaperDest *monitor)
SDL_DestroyTexture(monitor->wallpaper.layers[i].tex);
}
free(monitor->wallpaper.layers);
-}
+}*/
static int lerp(int a, int b, float t)
{
@@ -78,15 +86,9 @@ static int lerp(int a, int b, float t)
return (int)((float)a + (float)t * ((float)b - (float)a));
}
-void runWallpaperLoop(Config *cfg)
+void runWallpaperLoop(App *app)
{
- int quit = 0;
-
- if(!applyWallpapers(cfg))
- {
- lwpLog(LOG_ERROR, "Failed applying wallpapers");
- quit = 1;
- }
+ int quit = 0;
SDL_Event event;
@@ -95,117 +97,141 @@ void runWallpaperLoop(Config *cfg)
while (!quit)
{
- static int currentX = 0;
- static int currentY = 0;
+ static int currentX = 0;
+ static int currentY = 0;
- static int lastTicks = 0;
+ static int lastTicks = 0;
- int ticks = SDL_GetTicks();
- float dT = (ticks - lastTicks) / 1000.0f;
- lastTicks = ticks;
+ int ticks = SDL_GetTicks();
+ float dT = (ticks - lastTicks) / 1000.0f;
+ lastTicks = ticks;
#ifdef __WIN32
- POINT mPos;
- GetCursorPos(&mPos);
- mx = mPos.x - GetSystemMetrics(SM_XVIRTUALSCREEN);
- my = mPos.y - GetSystemMetrics(SM_YVIRTUALSCREEN);
+ POINT mPos;
+ GetCursorPos(&mPos);
+ mx = mPos.x - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ my = mPos.y - GetSystemMetrics(SM_YVIRTUALSCREEN);
#else
- SDL_GetGlobalMouseState(&mx, &my);
+ SDL_GetGlobalMouseState(&mx, &my);
#endif
- while (SDL_PollEvent(&event))
- if (event.type == SDL_QUIT) quit = 1;
+ while (SDL_PollEvent(&event))
+ if (event.type == SDL_QUIT) quit = 1;
+
+ currentX = lerp(currentX, mx, dT * 4); // 4: smooth
+ currentY = lerp(currentY, my, dT * 4);
+
+ for (int m = 0; m < app->monitorsCount; m++)
+ {
+ int relativeCurrentX = currentX - app->monitors[m].info.bounds.x;
+ int relativeCurrentY = currentY - app->monitors[m].info.bounds.y;
- currentX = lerp(currentX, mx, dT * cfg->smooth);
- currentY = lerp(currentY, my, dT * cfg->smooth);
+ if (relativeCurrentX < 0) relativeCurrentX = 0;
+ if (relativeCurrentY < 0) relativeCurrentY = 0;
+ if (relativeCurrentX > app->monitors[m].info.bounds.w)
+ relativeCurrentX = app->monitors[m].info.bounds.w;
+ if (relativeCurrentY > app->monitors[m].info.bounds.h)
+ relativeCurrentY = app->monitors[m].info.bounds.h;
- for (int m = 0; m < cfg->monitorsCount; m++)
+ if (SDL_SetRenderTarget(app->renderer, app->monitors[m].wlp.tex) != 0)
{
- int relativeCurrentX = currentX - cfg->monitors[m].x;
- int relativeCurrentY = currentY - cfg->monitors[m].y;
+ lwpLog(LOG_ERROR, "Error setting the renderer target: %s", SDL_GetError());
+ quit = 1;
+ }
+ SDL_RenderClear(app->renderer);
- if (relativeCurrentX < 0) relativeCurrentX = 0;
- if (relativeCurrentY < 0) relativeCurrentY = 0;
- if (relativeCurrentX > cfg->monitors[m].w) relativeCurrentX = cfg->monitors[m].w;
- if (relativeCurrentY > cfg->monitors[m].h) relativeCurrentY = cfg->monitors[m].h;
+ for (int i = 0; i < app->monitors[m].wlp.info.config.layersCount; i++)
+ {
+ SDL_Rect src = {
+ .x = 0,
+ .y = 0,
+ .w = app->monitors[m].wlp.originalW,
+ .h = app->monitors[m].wlp.originalH,
+ };
- SDL_SetRenderTarget(cfg->renderer, cfg->monitors[m].wallpaper.tex);
- SDL_RenderClear(cfg->renderer);
+ int x =
+ -((relativeCurrentX - app->monitors[m].info.bounds.w / 2) *
+ app->monitors[m].wlp.info.config.layerConfigs[i].sensitivityX);
+ int y =
+ -((relativeCurrentY - app->monitors[m].info.bounds.h / 2) *
+ app->monitors[m].wlp.info.config.layerConfigs[i].sensitivityY);
- for (int i = 0; i < cfg->monitors[m].wallpaper.layersCount; i++)
+ for (int k = -app->monitors[m].wlp.info.config.repeatY;
+ k <= app->monitors[m].wlp.info.config.repeatY;
+ k++)
{
- SDL_Rect src = {
- .x = 0,
- .y = 0,
- .w = cfg->monitors[m].wallpaper.originalW,
- .h = cfg->monitors[m].wallpaper.originalH,
- };
-
- int x =
- -((relativeCurrentX - cfg->monitors[m].w / 2) *
- cfg->monitors[m].wallpaper.layers[i].sensitivityX);
- int y =
- -((relativeCurrentY - cfg->monitors[m].h / 2) *
- cfg->monitors[m].wallpaper.layers[i].sensitivityY);
-
- for (int k = -cfg->monitors[m].wallpaper.repeatY; k <= cfg->monitors[m].wallpaper.repeatY;
- k++)
+ for (int j = -app->monitors[m].wlp.info.config.repeatX;
+ j <= app->monitors[m].wlp.info.config.repeatX;
+ j++)
{
- for (int j = -cfg->monitors[m].wallpaper.repeatX; j <= cfg->monitors[m].wallpaper.repeatX;
- j++)
+ SDL_Rect dest = {
+ .x = x + j * app->monitors[m].info.config.wlpBounds.w,
+ .y = y + k * app->monitors[m].info.config.wlpBounds.h,
+ .w = app->monitors[m].info.config.wlpBounds.w,
+ .h = app->monitors[m].info.config.wlpBounds.h,
+ };
+
+ if (SDL_RenderCopy(app->renderer, app->monitors[m].wlp.layers[i].tex, &src, &dest) != 0)
{
- SDL_Rect dest = {
- .x = x + j * cfg->monitors[m].wallpaperW,
- .y = y + k * cfg->monitors[m].wallpaperH,
- .w = cfg->monitors[m].wallpaperW,
- .h = cfg->monitors[m].wallpaperH,
- };
-
- SDL_RenderCopy(cfg->renderer, cfg->monitors[m].wallpaper.layers[i].tex, &src, &dest);
+ lwpLog(LOG_ERROR, "Error rendering copy: %s", SDL_GetError());
+ quit = 1;
}
}
}
+ }
- SDL_SetRenderTarget(cfg->renderer, cfg->monitors[m].tex);
-
- SDL_Rect src = {
- .x = 0,
- .y = 0,
- .w = cfg->monitors[m].wallpaperW,
- .h = cfg->monitors[m].wallpaperH,
- };
-
- SDL_Rect dest = {
- .x = cfg->monitors[m].wallpaperX,
- .y = cfg->monitors[m].wallpaperY,
- .w = cfg->monitors[m].wallpaperW,
- .h = cfg->monitors[m].wallpaperH,
- };
+ if (SDL_SetRenderTarget(app->renderer, app->monitors[m].tex) != 0)
+ {
+ lwpLog(LOG_ERROR, "Error setting the renderer target: %s", SDL_GetError());
+ quit = 1;
+ }
- SDL_RenderCopy(cfg->renderer, cfg->monitors[m].wallpaper.tex, &src, &dest);
+ SDL_Rect src = {
+ .x = 0,
+ .y = 0,
+ .w = app->monitors[m].info.config.wlpBounds.w,
+ .h = app->monitors[m].info.config.wlpBounds.h,
+ };
+
+ SDL_Rect dest = {
+ .x = app->monitors[m].info.config.wlpBounds.x,
+ .y = app->monitors[m].info.config.wlpBounds.y,
+ .w = app->monitors[m].info.config.wlpBounds.w,
+ .h = app->monitors[m].info.config.wlpBounds.h,
+ };
+
+ if (SDL_RenderCopy(app->renderer, app->monitors[m].wlp.tex, &src, &dest) != 0)
+ {
+ lwpLog(LOG_ERROR, "Error rendering copy: %s", SDL_GetError());
+ quit = 1;
+ }
- SDL_SetRenderTarget(cfg->renderer, NULL);
+ SDL_SetRenderTarget(app->renderer, NULL);
- SDL_Rect finalSrc = {
- .x = 0,
- .y = 0,
- .w = cfg->monitors[m].w,
- .h = cfg->monitors[m].h,
- };
+ SDL_Rect finalSrc = {
+ .x = 0,
+ .y = 0,
+ .w = app->monitors[m].info.bounds.w,
+ .h = app->monitors[m].info.bounds.h,
+ };
- SDL_Rect finalDest = {
- .x = cfg->monitors[m].x,
- .y = cfg->monitors[m].y,
- .w = cfg->monitors[m].w,
- .h = cfg->monitors[m].h,
- };
+ SDL_Rect finalDest = {
+ .x = app->monitors[m].info.bounds.x,
+ .y = app->monitors[m].info.bounds.y,
+ .w = app->monitors[m].info.bounds.w,
+ .h = app->monitors[m].info.bounds.h,
+ };
- SDL_RenderCopy(cfg->renderer, cfg->monitors[m].tex, &finalSrc, &finalDest);
+ if (SDL_RenderCopy(app->renderer, app->monitors[m].tex, &finalSrc, &finalDest) != 0)
+ {
+ lwpLog(LOG_ERROR, "Error rendering copy: %s", SDL_GetError());
+ quit = 1;
}
- SDL_RenderPresent(cfg->renderer);
- SDL_Delay(1000 / cfg->targetFPS);
+ }
+ SDL_RenderPresent(app->renderer);
+ SDL_Delay(1000 / app->config.targetFps);
#ifdef __WIN32
if (!updateTrayIcon()) quit = 1;
#endif
}
-}
\ No newline at end of file
+}
diff --git a/src/wlp/wallpaper.h b/src/wlp/wallpaper.h
index 92b1631..4da7889 100644
--- a/src/wlp/wallpaper.h
+++ b/src/wlp/wallpaper.h
@@ -3,8 +3,4 @@
#include "main.h"
-int applyWallpapers(Config *cfg);
-void freeMonitor(WallpaperDest *monitor);
-void runWallpaperLoop(Config *cfg);
-
#endif
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 2a4e61f..42075c6 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -63,8 +63,12 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_TRAY_ICON:
if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN)
{
- int res = MessageBox(NULL, "Do You want to run Layered WallPaper with debug console?",
- "Restart Layered WallPaper", MB_YESNOCANCEL | MB_ICONQUESTION);
+ int res = MessageBox(
+ NULL,
+ "Do You want to run Layered WallPaper with debug console?",
+ "Restart Layered WallPaper",
+ MB_YESNOCANCEL | MB_ICONQUESTION
+ );
TCHAR processParam = NULL;
@@ -104,8 +108,20 @@ void initTrayIcon()
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(0, CLASS_NAME, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+ HWND hWnd = CreateWindowEx(
+ 0,
+ CLASS_NAME,
+ L"",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ hInstance,
+ NULL
+ );
// Create tray icon
@@ -136,14 +152,20 @@ void initWindow(Config *cfg)
HWND wallpaperWorkerw = GetWindow(iconWorkerw, GW_HWNDNEXT);
SetParent(hWindow, wallpaperWorkerw);
- SetWindowLongPtr(hWindow, GWL_EXSTYLE,
- WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE);
+ SetWindowLongPtr(
+ hWindow, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE
+ );
SetWindowLongPtr(hWindow, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE);
- SetWindowPos(hWindow, NULL, 0, 0,
- GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN),
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
+ SetWindowPos(
+ hWindow,
+ NULL,
+ 0,
+ 0,
+ GetSystemMetrics(SM_CXVIRTUALSCREEN),
+ GetSystemMetrics(SM_CYVIRTUALSCREEN),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW
+ );
}
#elif __DARWIN
@@ -165,21 +187,30 @@ void initWindow(Config *cfg)
// Get shared NScfglication instance
const id ns_cfg = OBJC_MSG_CLS(objc_getClass("NScfglication"), sel_getUid("sharedcfglication"));
- OBJC_MSG_INT(ns_cfg, sel_getUid("setActivationPolicy:"),
- 0); // NScfglicationActivationPolicyRegular
+ OBJC_MSG_INT(
+ ns_cfg,
+ sel_getUid("setActivationPolicy:"),
+ 0
+ ); // NScfglicationActivationPolicyRegular
// Create NSWindow
const id window = ((id(*)(id, SEL, struct CGRect, int, int, int))objc_msgSend)(
OBJC_MSG_CLS(objc_getClass("NSWindow"), sel_getUid("alloc")),
- sel_getUid("initWithContentRect:styleMask:backing:defer:"), frameRect,
+ sel_getUid("initWithContentRect:styleMask:backing:defer:"),
+ frameRect,
0, // NSWindowStyleMaskBorderless
2, // NSBackingStoreBuffered
- false);
+ false
+ );
// Set window attributes
- OBJC_MSG_ID(window, sel_getUid("setTitle:"),
- OBJC_MSG_CLS_CHR(objc_getClass("NSString"), sel_getUid("stringWithUTF8String:"),
- "Parallax wallpaper"));
+ OBJC_MSG_ID(
+ window,
+ sel_getUid("setTitle:"),
+ OBJC_MSG_CLS_CHR(
+ objc_getClass("NSString"), sel_getUid("stringWithUTF8String:"), "Parallax wallpaper"
+ )
+ );
OBJC_MSG_PTR(window, sel_getUid("makeKeyAndOrderFront:"), nil);
OBJC_MSG_INT(window, sel_getUid("setLevel:"), kCGDesktopWindowLevel - 1);
OBJC_MSG_INT(ns_cfg, sel_getUid("activateIgnoringOthercfgs:"), true);
@@ -188,30 +219,43 @@ void initWindow(Config *cfg)
cfg->window = SDL_CreateWindowFrom((void *)window);
if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
}
+#endif
-#elif __LINUX
-
-void initWindow(Config *cfg)
+void initWindow(App *app)
{
- if (cfg->reloadRootWnd)
+ if (!app->config.drawOnRootWindow)
{
Display *display = XOpenDisplay(NULL);
XCloseDisplay(display);
- cfg->window = SDL_CreateWindow("Parallax wallpaper", 0, 0, DisplayWidth(display, 0),
- DisplayHeight(display, 0), SDL_WINDOW_OPENGL);
+ app->window = SDL_CreateWindow(
+ "Layered WallPaper",
+ 0,
+ 0,
+ DisplayWidth(display, 0),
+ DisplayHeight(display, 0),
+ SDL_WINDOW_OPENGL
+ );
SDL_SysWMinfo wmInfo;
SDL_GetVersion(&wmInfo.version);
- SDL_GetWindowWMInfo(cfg->window, &wmInfo);
+ SDL_GetWindowWMInfo(app->window, &wmInfo);
Window xWnd = wmInfo.info.x11.window;
display = wmInfo.info.x11.display;
Atom atomType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", 0);
Atom atomDesktop = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", 0);
- XChangeProperty(display, xWnd, atomType, XA_ATOM, 32, PropModeReplace,
- (const unsigned char *)&atomDesktop, 1);
+ XChangeProperty(
+ display,
+ xWnd,
+ atomType,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (const unsigned char *)&atomDesktop,
+ 1
+ );
Window rootWindow = RootWindow(display, DefaultScreen(display));
@@ -223,11 +267,13 @@ void initWindow(Config *cfg)
{
Display *display = XOpenDisplay(NULL);
Window rootWindow = RootWindow(display, DefaultScreen(display));
- cfg->window = SDL_CreateWindowFrom((void *)rootWindow);
+ app->window = SDL_CreateWindowFrom((void *)rootWindow);
XCloseDisplay(display);
}
- if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ if (app->window == NULL) lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
+ app->renderer =
+ SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (app->renderer == NULL) lwpLog(LOG_ERROR, "Failed to initialize renderer: %s", SDL_GetError());
}
-#endif
diff --git a/src/wlp/window.h b/src/wlp/window.h
index fc4a498..feffdf4 100644
--- a/src/wlp/window.h
+++ b/src/wlp/window.h
@@ -4,11 +4,9 @@
#include "main.h"
#include "parser.h"
-void initWindow(Config *cfg);
-
#ifdef __WIN32
void initTrayIcon();
-int updateTrayIcon();
+int updateTrayIcon();
void removeTrayIcon();
#endif
diff --git a/wallpapers/default-fullhd/wallpaper.cfg b/wallpapers/default-fullhd/wallpaper.cfg
index f2939f1..6276979 100644
--- a/wallpapers/default-fullhd/wallpaper.cfg
+++ b/wallpapers/default-fullhd/wallpaper.cfg
@@ -1,14 +1,5 @@
-# Layers count
-count=4
-
-# Base movement sensitivity
-# Sensitivity for each layer is [ movement_x * (i-1) ], where i is the layer index.
-movement_x=0.05
-movement_y=0.05
-
-# You can override base sensitivity for a specific layer like this:
-# movement2_x = 0.1
-
-# Set this to 1, if Your wallpaper is repeatable
-repeat_x=0
-repeat_y=0
+count=4;
+movement_x=0.05;
+movement_y=0.05;
+repeat_x=0;
+repeat_y=0;
From c568392b6d0b655309222abe7a9cf5191237b10f Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Wed, 31 Jan 2024 18:22:42 +0000
Subject: [PATCH 18/36] Fixed few bugs
---
src/common.h | 4 ++--
src/common/config.c | 26 +++++++++++++++++++++++---
src/common/monitorScanner.c | 20 ++++++++++----------
src/common/wallpaperScanner.c | 8 +++++---
src/wlp/main.c | 4 +---
src/wlp/wallpaper.c | 3 +++
6 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/src/common.h b/src/common.h
index ac50ff5..9314584 100644
--- a/src/common.h
+++ b/src/common.h
@@ -28,7 +28,7 @@ typedef struct
typedef struct
{
- int set;
+ int loaded;
int repeatX;
int repeatY;
int layersCount;
@@ -45,7 +45,7 @@ typedef struct
typedef struct
{
- int set;
+ int loaded;
char wlpName[WALLPAPER_NAME_MAX];
Bounds wlpBounds;
} MonitorConfig;
diff --git a/src/common/config.c b/src/common/config.c
index 9530b91..88d77ff 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -12,6 +12,14 @@ void getMonitorConfigPath(const char *name, char *path)
sprintf(path, "%s/.config/lwp/monitors/%s.cfg", g_get_home_dir(), name);
}
+void getWallpaperConfigPath(const char *dirName, char *path, int type)
+{
+ if (type == CONFIG_DEFAULT)
+ sprintf(path, "%s/wallpaper.cfg", dirName);
+ else
+ sprintf(path, "%s/wallpaper.cfg", dirName);
+}
+
void getAppConfigPath(char *path, int type)
{
if (type == CONFIG_DEFAULT)
@@ -54,6 +62,8 @@ void saveMonitorConfig(const char *name, MonitorConfig *mc)
int loadMonitorConfig(const char *name, MonitorConfig *mc)
{
+ mc->loaded = 0;
+
config_t cfg;
config_setting_t *root, *setting;
@@ -78,6 +88,7 @@ int loadMonitorConfig(const char *name, MonitorConfig *mc)
config_destroy(&cfg);
+ mc->loaded = 1;
return 1;
}
@@ -109,14 +120,21 @@ int loadAppConfig(AppConfig *ac)
int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc)
{
- char path[PATH_MAX];
- sprintf(path, "%s/wallpaper.cfg", dirName);
+ wc->loaded = 0;
config_t cfg;
config_setting_t *root, *setting;
config_init(&cfg);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+
+ char path[PATH_MAX];
+ getWallpaperConfigPath(dirName, path, CONFIG_USER);
+
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ {
+ getWallpaperConfigPath(dirName, path, CONFIG_DEFAULT);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ }
root = config_root_setting(&cfg);
setting = config_setting_get_member(root, "count");
@@ -143,5 +161,7 @@ int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc)
config_destroy(&cfg);
+ wc->loaded = 1;
+
return 1;
}
diff --git a/src/common/monitorScanner.c b/src/common/monitorScanner.c
index 0e562f3..78cd9e0 100644
--- a/src/common/monitorScanner.c
+++ b/src/common/monitorScanner.c
@@ -29,11 +29,11 @@ BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
monitorEnumIndex + 1,
info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : ""
);
- m[monitorEnumIndex].bounds.x = info.rcWork.left;
- m[monitorEnumIndex].bounds.y = info.rcWork.top;
- m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
- m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
- m[monitorEnumIndex].config.set = 0;
+ m[monitorEnumIndex].bounds.x = info.rcWork.left;
+ m[monitorEnumIndex].bounds.y = info.rcWork.top;
+ m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
+ m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
+ m[monitorEnumIndex].config.loaded = 0;
monitorEnumIndex++;
return TRUE;
@@ -63,11 +63,11 @@ MonitorInfo *scanMonitors(int *count)
while (i < monitorCount)
{
snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
- m[i].bounds.x = info->x;
- m[i].bounds.y = info->y;
- m[i].bounds.w = info->width;
- m[i].bounds.h = info->height;
- m[i].config.set = 0;
+ m[i].bounds.x = info->x;
+ m[i].bounds.y = info->y;
+ m[i].bounds.w = info->width;
+ m[i].bounds.h = info->height;
+ m[i].config.loaded = 0;
info++;
i++;
diff --git a/src/common/wallpaperScanner.c b/src/common/wallpaperScanner.c
index 2b835a2..9da8502 100644
--- a/src/common/wallpaperScanner.c
+++ b/src/common/wallpaperScanner.c
@@ -30,7 +30,8 @@ WallpaperInfo *scanWallpapers(int *count)
{
sprintf(ptr->name, "%s", filename);
sprintf(ptr->dirPath, "%s/%s", SYSTEM_WALLPAPERS_PATH, filename);
- ptr->isDefault = 1;
+ ptr->isDefault = 1;
+ ptr->config.loaded = 0;
ptr++;
}
@@ -38,8 +39,9 @@ WallpaperInfo *scanWallpapers(int *count)
while ((filename = g_dir_read_name(dir)))
{
sprintf(ptr->name, "%s", filename);
- sprintf(ptr->dirPath, "%s/%s", SYSTEM_WALLPAPERS_PATH, filename);
- ptr->isDefault = 0;
+ sprintf(ptr->dirPath, "%s/%s/%s", g_get_home_dir(), ".config/lwp/wallpapers", filename);
+ ptr->isDefault = 0;
+ ptr->config.loaded = 0;
ptr++;
}
diff --git a/src/wlp/main.c b/src/wlp/main.c
index 5c11052..454450f 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -84,7 +84,6 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape
if (!loadWallpaperConfig(m->wlp.info.dirPath, &m->wlp.info.config))
{
- m->wlp.info.config.set = 0;
lwpLog(LOG_WARNING, "Could not load the wallpaper config");
}
else
@@ -150,7 +149,7 @@ void initWallpaper(App *app, Monitor *m, WallpaperInfo *wallpapers, int wallpape
if (!foundWlp) lwpLog(LOG_WARNING, "Couldn't find the wallpaper. Ignoring...");
}
-void initMonitors(App *app)
+int initMonitors(App *app)
{
MonitorInfo *monitors = scanMonitors(&app->monitorsCount);
app->monitors = malloc(sizeof(Monitor) * app->monitorsCount);
@@ -170,7 +169,6 @@ void initMonitors(App *app)
if (!loadMonitorConfig(mi->name, &mi->config))
{
lwpLog(LOG_WARNING, "Couldn't find config file for monitor %s. Ignoring...", mi->name);
- mi->config.set = 0;
}
else
{
diff --git a/src/wlp/wallpaper.c b/src/wlp/wallpaper.c
index 1136bce..c08cfa3 100644
--- a/src/wlp/wallpaper.c
+++ b/src/wlp/wallpaper.c
@@ -123,6 +123,9 @@ void runWallpaperLoop(App *app)
for (int m = 0; m < app->monitorsCount; m++)
{
+ if (!app->monitors[m].info.config.loaded || !app->monitors[m].wlp.info.config.loaded)
+ continue;
+
int relativeCurrentX = currentX - app->monitors[m].info.bounds.x;
int relativeCurrentY = currentY - app->monitors[m].info.bounds.y;
From 740a70bbb35026612dcc32c5849f706faea0e651 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Wed, 31 Jan 2024 18:32:05 +0000
Subject: [PATCH 19/36] Cleaned code
---
src/core/main.c | 2 +
src/{wlp => }/platform_guard.h | 0
src/wlp/CMakeLists.txt | 2 +-
src/wlp/debug.c | 4 +-
src/wlp/debug.h | 10 -
src/wlp/main.c | 4 +-
src/wlp/main.h | 6 +
src/wlp/parser.c | 302 ------------------------------
src/wlp/parser.h | 10 -
src/wlp/{wallpaper.c => render.c} | 74 --------
src/wlp/wallpaper.h | 6 -
src/wlp/window.c | 1 -
src/wlp/window.h | 13 --
13 files changed, 12 insertions(+), 422 deletions(-)
rename src/{wlp => }/platform_guard.h (100%)
delete mode 100644 src/wlp/debug.h
delete mode 100644 src/wlp/parser.c
delete mode 100644 src/wlp/parser.h
rename src/wlp/{wallpaper.c => render.c} (75%)
delete mode 100644 src/wlp/wallpaper.h
delete mode 100644 src/wlp/window.h
diff --git a/src/core/main.c b/src/core/main.c
index 079cfa4..4fc2f52 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1,5 +1,7 @@
#include "main.h"
+#include "../platform_guard.h"
+
#ifdef __WIN32
#define MAIN_WINDOW_TEMPLATE_PATH "./window_templates/main.glade"
#elif __DARWIN
diff --git a/src/wlp/platform_guard.h b/src/platform_guard.h
similarity index 100%
rename from src/wlp/platform_guard.h
rename to src/platform_guard.h
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 0ddfdae..9dfcd42 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -8,7 +8,7 @@ set(_SOURCE_FILES
../common/wallpaperScanner.c
main.c
debug.c
- wallpaper.c
+ render.c
window.c
)
diff --git a/src/wlp/debug.c b/src/wlp/debug.c
index f66e7ee..5081129 100644
--- a/src/wlp/debug.c
+++ b/src/wlp/debug.c
@@ -1,8 +1,8 @@
-#include "debug.h"
-
#include
#include
+#include "main.h"
+
void lwpLog(int type, const char *str, ...)
{
char *typePrefix;
diff --git a/src/wlp/debug.h b/src/wlp/debug.h
deleted file mode 100644
index fde6f2a..0000000
--- a/src/wlp/debug.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#define LOG_ERROR 0
-#define LOG_INFO 1
-#define LOG_WARNING 2
-
-void lwpLog(int type, const char *str, ...);
-
-#endif
diff --git a/src/wlp/main.c b/src/wlp/main.c
index 454450f..cf402f9 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -1,8 +1,6 @@
#include "main.h"
-#include "debug.h"
-#include "platform_guard.h"
-#include "wallpaper.h"
+#include "../platform_guard.h"
#ifdef __WIN32
static void initCmd()
diff --git a/src/wlp/main.h b/src/wlp/main.h
index e799f2c..1d3daef 100644
--- a/src/wlp/main.h
+++ b/src/wlp/main.h
@@ -30,6 +30,10 @@
#include "../common.h"
+#define LOG_ERROR 0
+#define LOG_INFO 1
+#define LOG_WARNING 2
+
typedef struct
{
SDL_Texture *tex;
@@ -60,6 +64,8 @@ typedef struct
SDL_Renderer *renderer;
} App;
+void lwpLog(int type, const char *str, ...);
+
void initWindow(App *app);
void runWallpaperLoop(App *app);
diff --git a/src/wlp/parser.c b/src/wlp/parser.c
deleted file mode 100644
index 26a407c..0000000
--- a/src/wlp/parser.c
+++ /dev/null
@@ -1,302 +0,0 @@
-#include "parser.h"
-
-#include
-#include
-
-#include "debug.h"
-#include "wallpaper.h"
-
-#define TYPE_FLOAT 0
-#define TYPE_INT 1
-#define TYPE_STR 2
-
-#ifdef __WIN32
-static void getline(char **buff, size_t *buffSize, FILE *f)
-{
- long int startPos = ftell(f);
- int length = 1;
- char c;
- do
- {
- c = fgetc(f);
- length++;
- } while (c != '\n' && !feof(f));
-
- if (*buffSize < length)
- {
- *buff = realloc(*buff, length * sizeof(char));
- *buffSize = length * sizeof(char);
- }
-
- fseek(f, startPos, SEEK_SET);
-
- fgets(*buff, length - 1, f);
- (*buff)[length - 1] = '\0';
- fgetc(f);
-}
-#endif
-
-static FILE *openConfigFile()
-{
- FILE *f;
- char userConfigPath[PATH_MAX];
-
-#ifdef __WIN32
- strcpy(userConfigPath, getenv("AppData"));
- strcat(userConfigPath, "\\lwp\\lwp.cfg");
-#else
- char *xdgConfigHome = getenv("XDG_CONFIG_HOME");
- if (xdgConfigHome)
- {
- strcpy(userConfigPath, xdgConfigHome);
- strcat(userConfigPath, "/lwp/lwp.cfg");
- }
- else
- {
- struct passwd *pw = getpwuid(getuid());
- strcpy(userConfigPath, pw->pw_dir);
- strcat(userConfigPath, "/.config/lwp/lwp.cfg");
- }
-#endif
-
- f = fopen(userConfigPath, "r");
- if (!f)
- {
- lwpLog(LOG_INFO, "User config file not found, opening default config instead");
- char defaultConfigPath[PATH_MAX];
-#ifdef __WIN32
- GetModuleFileNameA(NULL, defaultConfigPath, PATH_MAX);
- char *ptr = defaultConfigPath + strlen(defaultConfigPath) - 1;
- while (*ptr != '\\') ptr--;
- *ptr = '\0';
- strcat(defaultConfigPath, "\\defaultWin.cfg");
-
- f = fopen(defaultConfigPath, "r");
-#elif __DARWIN
- strcpy(defaultConfigPath, "/Applications/Layered_WallPaper/lwp.cfg");
-
- f = fopen(defaultConfigPath, "r");
-#else
- char *sysConfDir = getenv("sysconfdir");
- if (sysConfDir)
- {
- strcpy(defaultConfigPath, sysConfDir);
- strcat(defaultConfigPath, "/lwp.cfg");
- }
- else
- strcpy(defaultConfigPath, "/etc/lwp.cfg");
-
- f = fopen(defaultConfigPath, "r");
-#endif
- if (!f) lwpLog(LOG_ERROR, "Default config file not found!");
- }
-
- return f;
-}
-
-static int findLine(FILE *f, const char *name, int type, void *output)
-{
- char *buff = NULL;
- size_t buffSize = 0;
-
- int found = 0;
-
- fseek(f, 0, SEEK_SET);
-
- do
- {
- getline(&buff, &buffSize, f);
-
- if (buffSize > 0 && buff[0] != '#')
- {
- if (strncmp(name, buff, strlen(name)) == 0)
- {
- char *valuePtr = buff;
- while (*valuePtr != '=' && *valuePtr != '\0')
- {
- valuePtr++;
- }
-
- if (*valuePtr == '=')
- {
- valuePtr++;
-
- if (valuePtr[strlen(valuePtr) - 1] == '\n') valuePtr[strlen(valuePtr) - 1] = '\0';
-
- found = 1;
-
- switch (type)
- {
- case TYPE_INT:
- *(int *)output = atoi(valuePtr);
- break;
- case TYPE_FLOAT:
- *(float *)output = atof(valuePtr);
- break;
- case TYPE_STR:
- strcpy((char *)output, valuePtr);
- break;
- }
- }
- }
- }
- } while (!found && buffSize > 0 && !feof(f));
-
- free(buff);
- return found;
-}
-
-int parseConfig(Config *cfg)
-{
- lwpLog(LOG_INFO, "Loading config file");
-
- FILE *f = openConfigFile();
-
- if (!findLine(f, "monitors", TYPE_INT, &cfg->monitorsCount))
- {
- lwpLog(LOG_ERROR, "Can't find line 'monitors' in config");
- return 0;
- }
- lwpLog(LOG_INFO, " monitors: %d", cfg->monitorsCount);
-
- if (!findLine(f, "smooth", TYPE_FLOAT, &cfg->smooth))
- {
- lwpLog(LOG_INFO, "Can't find line 'smooth' in config, setting to default value");
- cfg->smooth = 8;
- }
- lwpLog(LOG_INFO, " smooth: %f", cfg->smooth);
-
- if (!findLine(f, "target_fps", TYPE_INT, &cfg->targetFPS))
- {
- lwpLog(LOG_INFO, "Can't find line 'target_fps' in config, setting to default value");
- cfg->targetFPS = 60;
- }
- lwpLog(LOG_INFO, " target_fps: %d", cfg->targetFPS);
-
-#ifdef __LINUX
- if (!findLine(f, "reload_rootwindow", TYPE_INT, &cfg->reloadRootWnd))
- {
- lwpLog(LOG_ERROR, "Can't find line 'reload_rootwindow' in config");
- return 0;
- }
- lwpLog(LOG_INFO, " reload_rootwindow: %d", cfg->reloadRootWnd);
-#endif
-
- cfg->monitors = malloc(cfg->monitorsCount * sizeof(WallpaperDest));
-
- for (int m = 0; m < cfg->monitorsCount; m++)
- {
- char wallpaperPath[PATH_MAX];
-
- const int PARAMS_COUNT = 9;
-
- const char *paramStr[] = {"wallpaper", "x", "y", "w", "h",
- "wallpaper_x", "wallpaper_y", "wallpaper_w", "wallpaper_h"};
- void *outputs[] = {
- wallpaperPath,
- &cfg->monitors[m].x,
- &cfg->monitors[m].y,
- &cfg->monitors[m].w,
- &cfg->monitors[m].h,
- &cfg->monitors[m].wallpaperX,
- &cfg->monitors[m].wallpaperY,
- &cfg->monitors[m].wallpaperW,
- &cfg->monitors[m].wallpaperH,
- };
-
- char str[100];
-
- for (int p = 0; p < PARAMS_COUNT; p++)
- {
- snprintf(str, 100, "monitor%d_%s", m + 1, paramStr[p]);
- if (!findLine(f, str, (p == 0 ? TYPE_STR : TYPE_INT), outputs[p]))
- {
- lwpLog(LOG_ERROR, "Can't find line '%s' in config", str);
- return 0;
- }
- if(p > 0)
- lwpLog(LOG_INFO, " %s: %d", str, *(int*)(outputs[p]));
- }
-
-#ifdef __WIN32
- if (strlen(wallpaperPath) < 2)
- {
- GetModuleFileNameA(NULL, wallpaperPath, PATH_MAX);
- char *ptr = wallpaperPath + strlen(wallpaperPath) - 1;
- while (*ptr != '\\') ptr--;
- *ptr = '\0';
- strcat(wallpaperPath, "\\wallpapers\\default-fullhd");
- }
-#endif
-
- strncpy(cfg->monitors[m].wallpaper.dirPath, wallpaperPath, PATH_MAX);
- lwpLog(LOG_INFO, " monitor%d_wallpaper: %s", m+1, wallpaperPath);
- }
-
- fclose(f);
- lwpLog(LOG_INFO, "Config file loaded");
- return 1;
-}
-
-int parseWallpaperConfig(Wallpaper *wallpaper, const char *path)
-{
- lwpLog(LOG_INFO, "Loading wallpaper config");
- FILE *f = fopen(path, "r");
- if (!f)
- {
- lwpLog(LOG_ERROR, "Wallpaper config file (%s) doesn't exist", path);
- return 0;
- }
-
- float defaultMovementX, defaultMovementY;
-
- const int PARAMS_COUNT = 5;
- const char *paramStr[] = {"count", "movement_x", "movement_y", "repeat_x", "repeat_y"};
- const int types[] = {TYPE_INT, TYPE_FLOAT, TYPE_FLOAT, TYPE_INT, TYPE_INT};
- void *outputs[] = {
- &wallpaper->layersCount, &defaultMovementX, &defaultMovementY,
- &wallpaper->repeatX, &wallpaper->repeatY,
- };
-
- for (int p = 0; p < PARAMS_COUNT; p++)
- {
- if (!findLine(f, paramStr[p], types[p], outputs[p]))
- {
- lwpLog(LOG_ERROR, "Can't find line '%s' in config", paramStr[p]);
- return 0;
- }
-
- if (types[p] == TYPE_FLOAT)
- lwpLog(LOG_INFO, " %s: %f", paramStr[p], *(float*)(outputs[p]));
- else
- lwpLog(LOG_INFO, " %s: %d", paramStr[p], *(int*)(outputs[p]));
- }
- wallpaper->layers = malloc(wallpaper->layersCount * sizeof(Layer));
-
- lwpLog(LOG_INFO, " Each layer movements:");
-
- char str[100];
- for (int l = 0; l < wallpaper->layersCount; l++)
- {
- snprintf(str, 100, "movement%d_x", l + 1);
- if (!findLine(f, str, TYPE_FLOAT, &wallpaper->layers[l].sensitivityX))
- wallpaper->layers[l].sensitivityX = defaultMovementX * l;
- lwpLog(LOG_INFO, " %s: %f", str, wallpaper->layers[l].sensitivityX);
-
- snprintf(str, 100, "movement%d_y", l + 1);
- if (!findLine(f, str, TYPE_FLOAT, &wallpaper->layers[l].sensitivityY))
- wallpaper->layers[l].sensitivityY = defaultMovementY * l;
- lwpLog(LOG_INFO, " %s: %f", str, wallpaper->layers[l].sensitivityY);
- }
-
- fclose(f);
-
- lwpLog(LOG_INFO, "Wallpaper config file loaded");
- return 1;
-}
-
-void freeConfig(Config *cfg)
-{
- for (int i = 0; i < cfg->monitorsCount; i++) freeMonitor(&cfg->monitors[i]);
- free(cfg->monitors);
-}
diff --git a/src/wlp/parser.h b/src/wlp/parser.h
deleted file mode 100644
index d20603c..0000000
--- a/src/wlp/parser.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef PARSER_H
-#define PARSER_H
-
-#include "main.h"
-
-int parseConfig(Config *cfg);
-int parseWallpaperConfig(Wallpaper *wallpaper, const char *path);
-void freeConfig(Config *cfg);
-
-#endif
diff --git a/src/wlp/wallpaper.c b/src/wlp/render.c
similarity index 75%
rename from src/wlp/wallpaper.c
rename to src/wlp/render.c
index c08cfa3..95e27e2 100644
--- a/src/wlp/wallpaper.c
+++ b/src/wlp/render.c
@@ -4,81 +4,7 @@
#include
#endif
-#include "debug.h"
#include "main.h"
-/*
-static int appplyWallpaper(
- App *app, MonitorInfo *monitor, Wallpaper *wallpaper, const char *dirPath
-)
-{
- char path[PATH_MAX];
-
- snprintf(path, PATH_MAX, "%s/wallpaper.cfg", dirPath);
-
- if (!parseWallpaperConfig(wallpaper, path))
- {
- return 0;
- }
-
- for (int i = 0; i < wallpaper->layersCount; i++)
- {
- snprintf(path, PATH_MAX, "%s/%d.bmp", dirPath, i + 1);
-
- SDL_Surface *surf = SDL_LoadBMP(path);
- if (!surf)
- {
- lwpLog(LOG_ERROR, "File %s not found", path);
- return 0;
- }
-
- if (i == 0)
- {
- wallpaper->originalW = surf->w;
- wallpaper->originalH = surf->h;
- }
-
- wallpaper->layers[i].tex = SDL_CreateTextureFromSurface(cfg->renderer, surf);
-
- SDL_FreeSurface(surf);
- }
-
- wallpaper->tex = SDL_CreateTexture(
- cfg->renderer,
- SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_TARGET,
- monitor->wallpaperW,
- monitor->wallpaperH
- );
-
- monitor->tex = SDL_CreateTexture(
- cfg->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, monitor->w, monitor->h
- );
-
- return 1;
-}
-
-int initWallpapers(App *app)
-{
- for (int m = 0; m < app->monitorsCount; m++)
- if (!appplyWallpaper(
- app, &cfg->monitors[m], &cfg->monitors[m].wallpaper, cfg->monitors[m].wallpaper.dirPath
- ))
- return 0;
-
- return 1;
-}*/
-/*
-void freeMonitor(MonitorInfo *monitor)
-{
- SDL_DestroyTexture(monitor->tex);
- SDL_DestroyTexture(monitor->wallpaper.tex);
-
- for (int i = 0; i < monitor->wallpaper.layersCount; i++)
- {
- SDL_DestroyTexture(monitor->wallpaper.layers[i].tex);
- }
- free(monitor->wallpaper.layers);
-}*/
static int lerp(int a, int b, float t)
{
diff --git a/src/wlp/wallpaper.h b/src/wlp/wallpaper.h
deleted file mode 100644
index 4da7889..0000000
--- a/src/wlp/wallpaper.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef WALLPAPER_H
-#define WALLPAPER_H
-
-#include "main.h"
-
-#endif
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 42075c6..10a15af 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -1,4 +1,3 @@
-#include "debug.h"
#include "main.h"
#ifdef __WIN32
diff --git a/src/wlp/window.h b/src/wlp/window.h
deleted file mode 100644
index feffdf4..0000000
--- a/src/wlp/window.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef WINDOW_H
-#define WINDOW_H
-
-#include "main.h"
-#include "parser.h"
-
-#ifdef __WIN32
-void initTrayIcon();
-int updateTrayIcon();
-void removeTrayIcon();
-#endif
-
-#endif
From 91186233d5d0507a99a8be5c675a38f71c13c6ba Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Wed, 31 Jan 2024 18:41:34 +0000
Subject: [PATCH 20/36] Freeing memory at exit
---
src/wlp/main.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/wlp/main.c b/src/wlp/main.c
index cf402f9..c0a6b18 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -55,11 +55,24 @@ static App app;
static void atExit()
{
- // freeConfig(&cfg);
- /*
- SDL_DestroyRenderer(app.renderer);
- SDL_DestroyWindow(app.window);
- SDL_Quit();*/
+ for (int i = 0; i < app.monitorsCount; i++)
+ {
+ Monitor *m = app.monitors + i;
+ if (m->tex) SDL_DestroyTexture(m->tex);
+ if (m->wlp.tex) SDL_DestroyTexture(m->wlp.tex);
+
+ for (int l = 0; l < m->wlp.info.config.layersCount; l++)
+ SDL_DestroyTexture(m->wlp.layers[l].tex);
+ free(m->wlp.layers);
+
+ m++;
+ }
+ free(app.monitors);
+
+ if (app.renderer) SDL_DestroyRenderer(app.renderer);
+ if (app.window) SDL_DestroyWindow(app.window);
+
+ SDL_Quit();
}
void exitSignalHandler(int s)
@@ -194,6 +207,8 @@ int initMonitors(App *app)
int main(int argc, char *argv[])
{
+ memset(&app, 0, sizeof(App));
+
char pidStr[10];
sprintf(pidStr, "%d\0", getpid());
fputs(pidStr, stdout);
From 17fe38616891cc573a0bfd7c0bcef8fc6bc15076 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Wed, 31 Jan 2024 20:34:22 +0000
Subject: [PATCH 21/36] version label
---
src/core/CMakeLists.txt | 2 +-
src/core/main.c | 4 ++++
src/core/windowHandlers.c | 5 +++++
src/window_templates/main.glade | 3 ++-
4 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 1403137..aa7cf33 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -57,7 +57,7 @@ endif()
set_target_properties(lwp PROPERTIES ENABLE_EXPORTS on)
-target_compile_definitions(lwp PUBLIC __${_UNAME})
+target_compile_definitions(lwp PUBLIC __${_UNAME} PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(lwp PUBLIC ${_INCLUDE_DIRS})
target_link_libraries(lwp PRIVATE ${_LIBS})
diff --git a/src/core/main.c b/src/core/main.c
index 4fc2f52..e8fdcf6 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -25,6 +25,7 @@ GtkWidget *yPosSpinBtn = NULL;
GtkWidget *widthSpinBtn = NULL;
GtkWidget *heightSpinBtn = NULL;
GtkWidget *monitorNameLabel = NULL;
+GtkWidget *versionLabel = NULL;
static void reloadMonitorListBox()
{
@@ -71,6 +72,7 @@ static void activate(GtkApplication *app, gpointer userdata)
wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
monitorWnd = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow");
monitorListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_MonitorListBox");
+ versionLabel = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_VersionLabel");
wallpaperListBox =
(GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow_WallpaperListBox");
wallpaperComboBox =
@@ -87,6 +89,8 @@ static void activate(GtkApplication *app, gpointer userdata)
gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(monitorWnd), GTK_APPLICATION(app));
+ gtk_label_set_text(GTK_LABEL(versionLabel), PROGRAM_VERSION);
+
runWlp();
}
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 82aa588..bba23ab 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -52,6 +52,9 @@ G_MODULE_EXPORT void WallpaperManagerWindowShow()
G_MODULE_EXPORT void MonitorWindowClose() { gtk_widget_set_visible(monitorWnd, 0); }
G_MODULE_EXPORT void MonitorWindowShow()
{
+ // Clear wallpaper list
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(wallpaperComboBox));
+
// Load wallpaper list
int wlpCount;
WallpaperInfo *wlpList = scanWallpapers(&wlpCount);
@@ -100,3 +103,5 @@ G_MODULE_EXPORT void MonitorWindow_ApplyBtnClick()
killWlp();
runWlp();
}
+
+G_MODULE_EXPORT void MonitorWindow_ExitBtnClick() { gtk_widget_set_visible(monitorWnd, 0); }
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index b52a7e5..e91fcd9 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -190,7 +190,7 @@
True
False
-
+
True
False
11
@@ -558,6 +558,7 @@
True
True
True
+
False
From ea510237cc191244b9da2e651c8c639c7715c911 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Wed, 7 Feb 2024 16:40:29 +0100
Subject: [PATCH 22/36] Running on Windows (but wlp not moving
---
distributeDLLs.sh | 4 ++
src/common/config.c | 107 ++++++++++++++++++++--------------
src/common/monitorScanner.c | 57 ++++++++----------
src/common/wallpaperScanner.c | 71 +++++++++++++++-------
src/core/main.c | 1 +
src/wlp/debug.c | 17 +++++-
src/wlp/main.c | 60 -------------------
src/wlp/render.c | 3 -
src/wlp/window.c | 81 ++++++++++++-------------
9 files changed, 200 insertions(+), 201 deletions(-)
diff --git a/distributeDLLs.sh b/distributeDLLs.sh
index ccfcab3..6a8d53d 100644
--- a/distributeDLLs.sh
+++ b/distributeDLLs.sh
@@ -1,6 +1,9 @@
#!/bin/bash
mkdir -p dlls
+mkdir -p dlls/lib
+mkdir -p dlls/lib/gdk-pixbuf-2.0
+mkdir -p dlls/lib/gdk-pixbuf-2.0/2.10.0
echo
PS3='Choose the correct version of gdbus: '
@@ -15,5 +18,6 @@ done
echo "Preparing DLLs..."
ldd ./src/core/lwp.exe | grep '\/mingw.*\.dll' -o | xargs -I{} cp "{}" ./dlls/
+cp /mingw64/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache ./dlls/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
echo "Done"
\ No newline at end of file
diff --git a/src/common/config.c b/src/common/config.c
index 88d77ff..259af27 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -5,32 +5,47 @@
#include "../common.h"
#define CONFIG_DEFAULT 0
-#define CONFIG_USER 1
+#define CONFIG_USER 1
-void getMonitorConfigPath(const char *name, char *path)
-{
+void getMonitorConfigPath(const char *name, char *path) {
+#ifdef __WIN32
+ sprintf(path, "%s\\lwp\\monitors\\%s.cfg", g_get_user_data_dir(), name);
+#else
sprintf(path, "%s/.config/lwp/monitors/%s.cfg", g_get_home_dir(), name);
+#endif
}
-void getWallpaperConfigPath(const char *dirName, char *path, int type)
-{
+void getWallpaperConfigPath(const char *dirName, char *path, int type) {
if (type == CONFIG_DEFAULT)
sprintf(path, "%s/wallpaper.cfg", dirName);
else
sprintf(path, "%s/wallpaper.cfg", dirName);
}
-void getAppConfigPath(char *path, int type)
-{
+void getAppConfigPath(char *path, int type) {
+#ifdef __WIN32
+ if (type == CONFIG_DEFAULT)
+ sprintf(path, "/etc/lwp.cfg");
+ else
+ sprintf(path, "%s\\lwp\\lwp.cfg", g_get_user_data_dir());
+#else
if (type == CONFIG_DEFAULT)
sprintf(path, "/etc/lwp.cfg");
else
sprintf(path, "%s/.config/lwp/lwp.cfg", g_get_home_dir());
+#endif
+}
+
+static void generateEmptyMonitorConfig(MonitorConfig *mc) {
+ sprintf(mc->wlpName, "");
+ mc->wlpBounds.x = 0;
+ mc->wlpBounds.y = 0;
+ mc->wlpBounds.w = 1920;
+ mc->wlpBounds.h = 1080;
}
-void saveMonitorConfig(const char *name, MonitorConfig *mc)
-{
- config_t cfg;
+void saveMonitorConfig(const char *name, MonitorConfig *mc) {
+ config_t cfg;
config_setting_t *root, *setting;
config_init(&cfg);
@@ -51,8 +66,7 @@ void saveMonitorConfig(const char *name, MonitorConfig *mc)
char path[PATH_MAX];
getMonitorConfigPath(name, path);
- if (!config_write_file(&cfg, path))
- {
+ if (!config_write_file(&cfg, path)) {
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
}
@@ -60,30 +74,36 @@ void saveMonitorConfig(const char *name, MonitorConfig *mc)
config_destroy(&cfg);
}
-int loadMonitorConfig(const char *name, MonitorConfig *mc)
-{
+int loadMonitorConfig(const char *name, MonitorConfig *mc) {
mc->loaded = 0;
- config_t cfg;
+ config_t cfg;
config_setting_t *root, *setting;
char path[PATH_MAX];
getMonitorConfigPath(name, path);
+ if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) {
+ generateEmptyMonitorConfig(mc);
+ saveMonitorConfig(name, mc);
+ return 1;
+ }
+
config_init(&cfg);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ return 0;
root = config_root_setting(&cfg);
setting = config_setting_get_member(root, "wlpName");
strcpy(mc->wlpName, config_setting_get_string(setting));
- setting = config_setting_get_member(root, "x");
+ setting = config_setting_get_member(root, "x");
mc->wlpBounds.x = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "y");
+ setting = config_setting_get_member(root, "y");
mc->wlpBounds.y = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "w");
+ setting = config_setting_get_member(root, "w");
mc->wlpBounds.w = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "h");
+ setting = config_setting_get_member(root, "h");
mc->wlpBounds.h = config_setting_get_int(setting);
config_destroy(&cfg);
@@ -92,37 +112,37 @@ int loadMonitorConfig(const char *name, MonitorConfig *mc)
return 1;
}
-int loadAppConfig(AppConfig *ac)
-{
- config_t cfg;
+int loadAppConfig(AppConfig *ac) {
+ config_t cfg;
config_setting_t *root, *setting;
char path[PATH_MAX];
getAppConfigPath(path, CONFIG_USER);
config_init(&cfg);
- if (config_read_file(&cfg, path) == CONFIG_FALSE)
- {
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) {
getAppConfigPath(path, CONFIG_DEFAULT);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ return 0;
}
root = config_root_setting(&cfg);
- setting = config_setting_get_member(root, "draw_on_rootwindow");
+#ifdef __LINUX
+ setting = config_setting_get_member(root, "draw_on_rootwindow");
ac->drawOnRootWindow = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "target_fps");
- ac->targetFps = config_setting_get_int(setting);
+#endif
+ setting = config_setting_get_member(root, "target_fps");
+ ac->targetFps = config_setting_get_int(setting);
config_destroy(&cfg);
return 1;
}
-int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc)
-{
+int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc) {
wc->loaded = 0;
- config_t cfg;
+ config_t cfg;
config_setting_t *root, *setting;
config_init(&cfg);
@@ -130,29 +150,28 @@ int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc)
char path[PATH_MAX];
getWallpaperConfigPath(dirName, path, CONFIG_USER);
- if (config_read_file(&cfg, path) == CONFIG_FALSE)
- {
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) {
getWallpaperConfigPath(dirName, path, CONFIG_DEFAULT);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ return 0;
}
root = config_root_setting(&cfg);
- setting = config_setting_get_member(root, "count");
+ setting = config_setting_get_member(root, "count");
wc->layersCount = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "repeat_x");
- wc->repeatX = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "repeat_y");
- wc->repeatY = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_x");
+ wc->repeatX = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_y");
+ wc->repeatY = config_setting_get_int(setting);
wc->layerConfigs = malloc(wc->layersCount * sizeof(LayerConfig));
- setting = config_setting_get_member(root, "movement_x");
+ setting = config_setting_get_member(root, "movement_x");
float movX = config_setting_get_float(setting);
- setting = config_setting_get_member(root, "movement_y");
+ setting = config_setting_get_member(root, "movement_y");
float movY = config_setting_get_float(setting);
- for (int i = 0; i < wc->layersCount; i++)
- {
+ for (int i = 0; i < wc->layersCount; i++) {
LayerConfig *lc = wc->layerConfigs + i;
lc->sensitivityX = movX * i;
diff --git a/src/common/monitorScanner.c b/src/common/monitorScanner.c
index 78cd9e0..39882a7 100644
--- a/src/common/monitorScanner.c
+++ b/src/common/monitorScanner.c
@@ -13,60 +13,53 @@
#ifdef __WIN32
int monitorEnumIndex = 0;
-BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
-{
+static BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect,
+ LPARAM param) {
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
- Monitor *m = (Monitor *)param;
-
- snprintf(
- m[monitorEnumIndex].name,
- MONITOR_NAME_MAX,
- "Monitor %d%s",
- monitorEnumIndex + 1,
- info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : ""
- );
- m[monitorEnumIndex].bounds.x = info.rcWork.left;
- m[monitorEnumIndex].bounds.y = info.rcWork.top;
- m[monitorEnumIndex].bounds.w = info.rcWork.right - info.rcWork.left;
- m[monitorEnumIndex].bounds.h = info.rcWork.bottom - info.rcWork.top;
- m[monitorEnumIndex].config.loaded = 0;
+ MonitorInfo *mi = (MonitorInfo *)param + monitorEnumIndex;
+
+ snprintf(mi->name, MONITOR_NAME_MAX, "Monitor %d%s", monitorEnumIndex + 1,
+ info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : "");
+ mi->bounds.x = info.rcWork.left;
+ mi->bounds.y = info.rcWork.top;
+ mi->bounds.w = info.rcWork.right - info.rcWork.left;
+ mi->bounds.h = info.rcWork.bottom - info.rcWork.top;
+ mi->config.loaded = 0;
monitorEnumIndex++;
return TRUE;
}
#endif
-MonitorInfo *scanMonitors(int *count)
-{
- int monitorCount;
+MonitorInfo *scanMonitors(int *count) {
MonitorInfo *m = NULL;
#ifdef __WIN32
- monitorCount = GetSystemMetrics(SM_CMONITORS);
- m = malloc(sizeof(Monitor) * monitorCount);
-
monitorEnumIndex = 0;
+ *count = GetSystemMetrics(SM_CMONITORS);
+ m = malloc(sizeof(MonitorInfo) * (*count));
+
EnumDisplayMonitors(NULL, NULL, &monitorenumproc, (LPARAM)m);
#else
- Display *display = XOpenDisplay((getenv("DISPLAY")));
- Window wnd = DefaultRootWindow(display);
- XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
+ Display *display = XOpenDisplay((getenv("DISPLAY")));
+ Window wnd = DefaultRootWindow(display);
+ XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
m = malloc(sizeof(MonitorInfo) * monitorCount);
int i = 0;
- while (i < monitorCount)
- {
- snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
- m[i].bounds.x = info->x;
- m[i].bounds.y = info->y;
- m[i].bounds.w = info->width;
- m[i].bounds.h = info->height;
+ while (i < monitorCount) {
+ snprintf(m[i].name, MONITOR_NAME_MAX, "%s",
+ XGetAtomName(display, info->name));
+ m[i].bounds.x = info->x;
+ m[i].bounds.y = info->y;
+ m[i].bounds.w = info->width;
+ m[i].bounds.h = info->height;
m[i].config.loaded = 0;
info++;
diff --git a/src/common/wallpaperScanner.c b/src/common/wallpaperScanner.c
index 9da8502..981b128 100644
--- a/src/common/wallpaperScanner.c
+++ b/src/common/wallpaperScanner.c
@@ -3,44 +3,75 @@
#include "../common.h"
-#define SYSTEM_WALLPAPERS_PATH "/usr/local/share/lwp/wallpapers"
+#define WALLPAPERS_SYSTEM 0
+#define WALLPAPERS_USER 1
-WallpaperInfo *scanWallpapers(int *count)
-{
+static void getWallpapersDirPath(char *path, int type) {
+#ifdef __WIN32
+ if (type == WALLPAPERS_USER)
+ sprintf(path, "%s\\lwp\\wallpapers", g_get_user_data_dir());
+ else {
+ char currentDirPath[PATH_MAX];
+ GetModuleFileNameA(NULL, currentDirPath, PATH_MAX);
+ char *ptr = currentDirPath+strlen(currentDirPath)-1;
+ while(*ptr != '\\')
+ ptr--;
+ *ptr = '\0';
+ sprintf(path, "%s\\wallpapers", currentDirPath);
+ }
+#else
+ if (type == WALLPAPERS_USER)
+ sprintf(path, "%s/.config/lwp/wallpapers", g_get_home_dir());
+ else
+ sprintf(path, "/usr/local/share/lwp/wallpapers");
+#endif
+}
+
+WallpaperInfo *scanWallpapers(int *count) {
*count = 0;
char userWlpPath[PATH_MAX];
+ getWallpapersDirPath(userWlpPath, WALLPAPERS_USER);
+ char systemWlpPath[PATH_MAX];
+ getWallpapersDirPath(systemWlpPath, WALLPAPERS_SYSTEM);
- sprintf(userWlpPath, "%s/.config/lwp/wallpapers", g_get_home_dir());
-
- GDir *dir;
- GError *error;
+ GDir *dir;
+ GError *error;
const gchar *filename;
- dir = g_dir_open(SYSTEM_WALLPAPERS_PATH, 0, &error);
- while ((g_dir_read_name(dir))) (*count)++;
+ dir = g_dir_open(systemWlpPath, 0, &error);
+ while ((g_dir_read_name(dir)))
+ (*count)++;
dir = g_dir_open(userWlpPath, 0, &error);
- while ((g_dir_read_name(dir))) (*count)++;
+ while ((g_dir_read_name(dir)))
+ (*count)++;
WallpaperInfo *list = malloc(sizeof(WallpaperInfo) * (*count));
- WallpaperInfo *ptr = list;
+ WallpaperInfo *ptr = list;
- dir = g_dir_open(SYSTEM_WALLPAPERS_PATH, 0, &error);
- while ((filename = g_dir_read_name(dir)))
- {
+ dir = g_dir_open(systemWlpPath, 0, &error);
+ while ((filename = g_dir_read_name(dir))) {
sprintf(ptr->name, "%s", filename);
- sprintf(ptr->dirPath, "%s/%s", SYSTEM_WALLPAPERS_PATH, filename);
- ptr->isDefault = 1;
+#ifdef __WIN32
+ sprintf(ptr->dirPath, "%s\\%s", systemWlpPath, filename);
+
+#else
+ sprintf(ptr->dirPath, "%s/%s", systemWlpPath, filename);
+#endif
+ ptr->isDefault = 1;
ptr->config.loaded = 0;
ptr++;
}
dir = g_dir_open(userWlpPath, 0, &error);
- while ((filename = g_dir_read_name(dir)))
- {
+ while ((filename = g_dir_read_name(dir))) {
sprintf(ptr->name, "%s", filename);
- sprintf(ptr->dirPath, "%s/%s/%s", g_get_home_dir(), ".config/lwp/wallpapers", filename);
- ptr->isDefault = 0;
+#ifdef __WIN32
+ sprintf(ptr->dirPath, "%s\\%s", userWlpPath, filename);
+#else
+ sprintf(ptr->dirPath, "%s/%s", userWlpPath, filename);
+#endif
+ ptr->isDefault = 0;
ptr->config.loaded = 0;
ptr++;
}
diff --git a/src/core/main.c b/src/core/main.c
index e8fdcf6..2ca6294 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -47,6 +47,7 @@ static void reloadMonitorListBox()
for (int i = 0; i < monitorsCount; i++)
{
+ printf("%s\n", monitors[i].name);
GtkWidget *label = gtk_label_new(monitors[i].name);
GtkWidget *row = gtk_list_box_row_new();
gtk_container_add(GTK_CONTAINER(row), label);
diff --git a/src/wlp/debug.c b/src/wlp/debug.c
index 5081129..d8b15c3 100644
--- a/src/wlp/debug.c
+++ b/src/wlp/debug.c
@@ -1,13 +1,26 @@
#include
#include
+#include
#include "main.h"
+void getLogFilePath(char *path)
+{
+ #ifdef __WIN32
+ sprintf(path, "%s\\lwp\\lwp.log", g_get_user_data_dir());
+ #else
+ sprintf(path, "/home/cziken/.config/lwp/log");
+ #endif
+}
+
void lwpLog(int type, const char *str, ...)
{
- char *typePrefix;
+ char path[PATH_MAX];
+ getLogFilePath(path);
+
+ FILE *file = fopen(path, "a");
- FILE *file = fopen("/home/cziken/.config/lwp/log", "a");
+ char *typePrefix;
switch (type)
{
diff --git a/src/wlp/main.c b/src/wlp/main.c
index c0a6b18..a3c399a 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -2,55 +2,6 @@
#include "../platform_guard.h"
-#ifdef __WIN32
-static void initCmd()
-{
- // Create console
- AllocConsole();
- AttachConsole(ATTACH_PARENT_PROCESS);
- freopen("CONOUT$", "w", stdout);
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD dwMode = 0;
- GetConsoleMode(hOut, &dwMode);
- SetConsoleMode(hOut, dwMode | 0x0004);
-
- // Remove closing button (because closing it closes the entire app)
- HWND hwnd = GetConsoleWindow();
- HMENU hMenu = GetSystemMenu(hwnd, FALSE);
- DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
-
- // Set console title
- SetConsoleTitle("Layered WallPaper");
-}
-BOOLmonitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
-{
- int px = GetSystemMetrics(SM_XVIRTUALSCREEN);
- int py = GetSystemMetrics(SM_YVIRTUALSCREEN);
-
- MONITORINFO monitorInfo;
- monitorInfo.cbSize = sizeof(MONITORINFO);
-
- GetMonitorInfo(monitor, &monitorInfo);
- lwpLog(
- LOG_INFO,
- " Monitor: position %ldx%ld, size %ldx%ld %s",
- monitorInfo.rcMonitor.left - px,
- monitorInfo.rcMonitor.top - py,
- monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
- monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
- (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY ? "primary" : ""
- );
-
- return TRUE;
-}
-/*
-static void scanMonitors()
-{
- lwpLog(LOG_INFO, "Scanning monitors...");
- EnumDisplayMonitors(NULL, NULL, &monitorenumproc, NULL);
-}*/
-#endif
-
static App app;
static void atExit()
@@ -223,13 +174,6 @@ int main(int argc, char *argv[])
lwpLog(LOG_INFO, "Starting Layered WallPaper");
-#ifdef __WIN32
- if (argc == 2 && strcmp(argv[1], "/console") == 0) initCmd();
- initTrayIcon();
-
- // scanMonitors();
-#endif
-
lwpLog(LOG_INFO, "Loading app config");
loadAppConfig(&app.config);
@@ -247,9 +191,5 @@ int main(int argc, char *argv[])
lwpLog(LOG_INFO, "Starting wallpaper loop");
runWallpaperLoop(&app);
-#ifdef __WIN32
- removeTrayIcon();
-#endif
-
return 0;
}
diff --git a/src/wlp/render.c b/src/wlp/render.c
index 95e27e2..baec2c4 100644
--- a/src/wlp/render.c
+++ b/src/wlp/render.c
@@ -159,8 +159,5 @@ void runWallpaperLoop(App *app)
}
SDL_RenderPresent(app->renderer);
SDL_Delay(1000 / app->config.targetFps);
-#ifdef __WIN32
- if (!updateTrayIcon()) quit = 1;
-#endif
}
}
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 10a15af..659d539 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -3,11 +3,7 @@
#ifdef __WIN32
#include
#include
-#ifdef _MSC_VER
-#include
-#else
#include
-#endif // _MSC_VER
#endif // __WIN32
#ifdef __LINUX
@@ -35,7 +31,7 @@ static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam)
}
return TRUE;
}
-
+/*
#define WM_TRAY_ICON (WM_USER + 1)
static NOTIFYICONDATA nid;
@@ -131,41 +127,7 @@ void initTrayIcon()
nid.uFlags = NIF_ICON | NIF_MESSAGE;
Shell_NotifyIcon(NIM_ADD, &nid);
-}
-
-void initWindow(Config *cfg)
-{
- cfg->window =
- SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
- if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
-
- SDL_SysWMinfo sysWmInfo;
- SDL_VERSION(&sysWmInfo.version)
- SDL_GetWindowWMInfo(cfg->window, &sysWmInfo);
- HWND hWindow = sysWmInfo.info.win.window;
-
- HWND progman = FindWindow("Progman", NULL);
- iconWorkerw = progman;
- SendMessageTimeout(progman, 0x052C, NULL, NULL, SMTO_NORMAL, 1000, NULL);
- if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL)) EnumWindows(getIconWorkerw, NULL);
-
- HWND wallpaperWorkerw = GetWindow(iconWorkerw, GW_HWNDNEXT);
- SetParent(hWindow, wallpaperWorkerw);
- SetWindowLongPtr(
- hWindow, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE
- );
- SetWindowLongPtr(hWindow, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE);
-
- SetWindowPos(
- hWindow,
- NULL,
- 0,
- 0,
- GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN),
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW
- );
-}
+}*/
#elif __DARWIN
@@ -222,6 +184,43 @@ void initWindow(Config *cfg)
void initWindow(App *app)
{
+ #ifdef __WIN32
+
+ app->window =
+ SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
+ if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+
+ SDL_SysWMinfo sysWmInfo;
+ SDL_VERSION(&sysWmInfo.version)
+ SDL_GetWindowWMInfo(app->window, &sysWmInfo);
+ HWND hWindow = sysWmInfo.info.win.window;
+
+ HWND progman = FindWindow("Progman", NULL);
+ iconWorkerw = progman;
+ SendMessageTimeout(progman, 0x052C, NULL, NULL, SMTO_NORMAL, 1000, NULL);
+ if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL)) EnumWindows(getIconWorkerw, NULL);
+
+ HWND wallpaperWorkerw = GetWindow(iconWorkerw, GW_HWNDNEXT);
+ SetParent(hWindow, wallpaperWorkerw);
+ SetWindowLongPtr(
+ hWindow, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE
+ );
+ SetWindowLongPtr(hWindow, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE);
+
+ SetWindowPos(
+ hWindow,
+ NULL,
+ 0,
+ 0,
+ GetSystemMetrics(SM_CXVIRTUALSCREEN),
+ GetSystemMetrics(SM_CYVIRTUALSCREEN),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW
+ );
+
+ #elif __DARWIN
+
+ #else
+
if (!app->config.drawOnRootWindow)
{
Display *display = XOpenDisplay(NULL);
@@ -270,6 +269,8 @@ void initWindow(App *app)
XCloseDisplay(display);
}
+ #endif
+
if (app->window == NULL) lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
app->renderer =
From 71d9672cf072209b608cb9acb7b876c05be39e76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Thu, 8 Feb 2024 13:08:00 +0100
Subject: [PATCH 23/36] Tray icon
---
src/core/CMakeLists.txt | 7 +-
src/core/main.c | 5 +-
src/core/main.h | 5 +
src/core/trayIcon.c | 63 ++++++++++
src/wlp/CMakeLists.txt | 6 +-
src/wlp/window.c | 261 +++++++++++-----------------------------
6 files changed, 144 insertions(+), 203 deletions(-)
create mode 100644 src/core/trayIcon.c
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index aa7cf33..cc0a414 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -2,6 +2,7 @@ set(_SOURCE_FILES
main.c
windowHandlers.c
wlp.c
+ trayIcon.c
../common/monitorScanner.c
../common/config.c
../common/wallpaperScanner.c
@@ -47,14 +48,12 @@ list(APPEND _LIBS ${libconfig_LINK_LIBRARIES})
# Main executable
if (_UNAME STREQUAL "DARWIN")
add_executable(lwp MACOSX_BUNDLE ${_SOURCE_FILES})
+elseif(_UNAME STREQUAL "WIN32")
+ add_executable(lwp WIN32 ${_SOURCE_FILES})
else()
add_executable(lwp ${_SOURCE_FILES})
endif()
-if(MSVC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
-endif()
-
set_target_properties(lwp PROPERTIES ENABLE_EXPORTS on)
target_compile_definitions(lwp PUBLIC __${_UNAME} PROGRAM_VERSION="${PROGRAM_VERSION}")
diff --git a/src/core/main.c b/src/core/main.c
index 2ca6294..8514ce4 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -47,7 +47,6 @@ static void reloadMonitorListBox()
for (int i = 0; i < monitorsCount; i++)
{
- printf("%s\n", monitors[i].name);
GtkWidget *label = gtk_label_new(monitors[i].name);
GtkWidget *row = gtk_list_box_row_new();
gtk_container_add(GTK_CONTAINER(row), label);
@@ -104,10 +103,14 @@ int main(int argc, char *argv[])
{
int status;
+ initTrayIcon();
+
app = gtk_application_new("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
+ removeTrayIcon();
+
return status;
}
diff --git a/src/core/main.h b/src/core/main.h
index add9ac0..7b17497 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -23,4 +23,9 @@ extern GtkWidget *monitorNameLabel;
void runWlp();
void killWlp();
+#ifdef __WIN32
+void initTrayIcon();
+void removeTrayIcon();
+#endif
+
#endif
diff --git a/src/core/trayIcon.c b/src/core/trayIcon.c
new file mode 100644
index 0000000..1b17ac0
--- /dev/null
+++ b/src/core/trayIcon.c
@@ -0,0 +1,63 @@
+#ifdef __WIN32
+
+#include "main.h"
+
+#include
+#include
+#include
+
+
+#define WM_TRAY_ICON (WM_USER + 1)
+
+static NOTIFYICONDATA nid;
+
+void removeTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid); }
+
+int updateTrayIcon() {
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 1;
+}
+
+static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam) {
+ switch (uMsg) {
+ case WM_TRAY_ICON:
+ if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN) {
+ gtk_widget_set_visible(mainWnd, 1);
+ }
+ break;
+ }
+}
+
+void initTrayIcon() {
+ // Create an invisible window to process tray icon events
+
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+ const TCHAR CLASS_NAME[] = TEXT("Hidden Window");
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof(WNDCLASS));
+ wc.lpfnWndProc = wndProc;
+ wc.hInstance = hInstance;
+ wc.lpszClassName = CLASS_NAME;
+ RegisterClass(&wc);
+ HWND hWnd = CreateWindowEx(0, CLASS_NAME, TEXT(""), WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+
+ // Create tray icon
+
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
+ nid.uCallbackMessage = WM_TRAY_ICON;
+ nid.hIcon = LoadIcon(hInstance, "ID");
+ nid.uFlags = NIF_ICON | NIF_MESSAGE;
+
+ Shell_NotifyIcon(NIM_ADD, &nid);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 9dfcd42..6e03f2d 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -56,6 +56,8 @@ option(LWP_INSTALL_LAUNCHD "Launch lwp on login (MacOSX only)" OFF)
# Main executable
if (_UNAME STREQUAL "DARWIN")
add_executable(lwpwlp MACOSX_BUNDLE ${_SOURCE_FILES})
+elseif(_UNAME STREQUAL "WIN32")
+ add_executable(lwpwlp WIN32 ${_SOURCE_FILES})
else()
add_executable(lwpwlp ${_SOURCE_FILES})
endif()
@@ -65,10 +67,6 @@ if(_UNAME STREQUAL "WIN32")
set_property(TARGET lwpwlp PROPERTY VS_DPI_AWARE "PerMonitor")
endif()
-if(MSVC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
-endif()
-
target_compile_definitions(lwpwlp PUBLIC __${_UNAME})
target_include_directories(lwpwlp PUBLIC ${_INCLUDE_DIRS})
target_link_libraries(lwpwlp PRIVATE ${_LIBS})
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 659d539..96b684d 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -1,194 +1,86 @@
#include "main.h"
#ifdef __WIN32
-#include
-#include
#include
-#endif // __WIN32
+#endif // __WIN32
#ifdef __LINUX
#include
#include
#include
-#endif //__LINUX
+#endif //__LINUX
#ifdef __WIN32
-static HWND iconWorkerw;
-static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam)
-{
+static HWND iconWorkerw;
+static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam) {
char buff[10];
GetClassName(hWnd, buff, 10);
- if (strcmp(buff, "WorkerW") == 0)
- {
+ if (strcmp(buff, "WorkerW") == 0) {
HWND defView = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL);
- if (defView)
- {
+ if (defView) {
iconWorkerw = hWnd;
return FALSE;
}
}
return TRUE;
}
-/*
-#define WM_TRAY_ICON (WM_USER + 1)
-
-static NOTIFYICONDATA nid;
-static int quit = 0;
-
-void removeTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid); }
-
-int updateTrayIcon()
-{
- MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return !quit;
-}
-
-static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_TRAY_ICON:
- if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN)
- {
- int res = MessageBox(
- NULL,
- "Do You want to run Layered WallPaper with debug console?",
- "Restart Layered WallPaper",
- MB_YESNOCANCEL | MB_ICONQUESTION
- );
-
- TCHAR processParam = NULL;
-
- if (res != IDCANCEL)
- {
- TCHAR fileName[MAX_PATH];
- GetModuleFileName(NULL, fileName, MAX_PATH);
-
- TCHAR cmd[MAX_PATH + 10];
- _tcscpy(cmd, fileName);
-
- if (res == IDYES) _tcscat(cmd, " /console");
-
- STARTUPINFO si;
- memset(&si, 0, sizeof(STARTUPINFO));
-
- PROCESS_INFORMATION pi;
-
- CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
-
- quit = 1;
- }
- }
- break;
- }
-}
-
-void initTrayIcon()
-{
- // Create an invisible window to process tray icon events
-
- HINSTANCE hInstance = GetModuleHandle(NULL);
- const wchar_t CLASS_NAME[] = L"Hidden Window";
- WNDCLASS wc;
- memset(&wc, 0, sizeof(WNDCLASS));
- wc.lpfnWndProc = wndProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(
- 0,
- CLASS_NAME,
- L"",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
-
- // Create tray icon
-
- nid.cbSize = sizeof(NOTIFYICONDATA);
- nid.hWnd = hWnd;
- nid.uCallbackMessage = WM_TRAY_ICON;
- nid.hIcon = LoadIcon(hInstance, "ID");
- nid.uFlags = NIF_ICON | NIF_MESSAGE;
-
- Shell_NotifyIcon(NIM_ADD, &nid);
-}*/
#elif __DARWIN
// Helper macros for objc runtime interaction
-#define OBJC_MSG_INT ((id(*)(id, SEL, int))objc_msgSend)
-#define OBJC_MSG_ID ((id(*)(id, SEL, id))objc_msgSend)
-#define OBJC_MSG_PTR ((id(*)(id, SEL, void *))objc_msgSend)
-#define OBJC_MSG_CLS ((id(*)(Class, SEL))objc_msgSend)
+#define OBJC_MSG_INT ((id(*)(id, SEL, int))objc_msgSend)
+#define OBJC_MSG_ID ((id(*)(id, SEL, id))objc_msgSend)
+#define OBJC_MSG_PTR ((id(*)(id, SEL, void *))objc_msgSend)
+#define OBJC_MSG_CLS ((id(*)(Class, SEL))objc_msgSend)
#define OBJC_MSG_CLS_CHR ((id(*)(Class, SEL, char *))objc_msgSend)
-void initWindow(Config *cfg)
-{
+void initWindow(Config *cfg) {
// Get main display size
const CGDirectDisplayID displayID = CGMainDisplayID();
- const size_t w = CGDisplayPixelsWide(displayID);
- const size_t h = CGDisplayPixelsHigh(displayID);
- const struct CGRect frameRect = {0, 0, w, h};
+ const size_t w = CGDisplayPixelsWide(displayID);
+ const size_t h = CGDisplayPixelsHigh(displayID);
+ const struct CGRect frameRect = {0, 0, w, h};
// Get shared NScfglication instance
- const id ns_cfg = OBJC_MSG_CLS(objc_getClass("NScfglication"), sel_getUid("sharedcfglication"));
- OBJC_MSG_INT(
- ns_cfg,
- sel_getUid("setActivationPolicy:"),
- 0
- ); // NScfglicationActivationPolicyRegular
+ const id ns_cfg = OBJC_MSG_CLS(objc_getClass("NScfglication"),
+ sel_getUid("sharedcfglication"));
+ OBJC_MSG_INT(ns_cfg, sel_getUid("setActivationPolicy:"),
+ 0); // NScfglicationActivationPolicyRegular
// Create NSWindow
- const id window = ((id(*)(id, SEL, struct CGRect, int, int, int))objc_msgSend)(
- OBJC_MSG_CLS(objc_getClass("NSWindow"), sel_getUid("alloc")),
- sel_getUid("initWithContentRect:styleMask:backing:defer:"),
- frameRect,
- 0, // NSWindowStyleMaskBorderless
- 2, // NSBackingStoreBuffered
- false
- );
+ const id window =
+ ((id(*)(id, SEL, struct CGRect, int, int, int))objc_msgSend)(
+ OBJC_MSG_CLS(objc_getClass("NSWindow"), sel_getUid("alloc")),
+ sel_getUid("initWithContentRect:styleMask:backing:defer:"), frameRect,
+ 0, // NSWindowStyleMaskBorderless
+ 2, // NSBackingStoreBuffered
+ false);
// Set window attributes
- OBJC_MSG_ID(
- window,
- sel_getUid("setTitle:"),
- OBJC_MSG_CLS_CHR(
- objc_getClass("NSString"), sel_getUid("stringWithUTF8String:"), "Parallax wallpaper"
- )
- );
+ OBJC_MSG_ID(window, sel_getUid("setTitle:"),
+ OBJC_MSG_CLS_CHR(objc_getClass("NSString"),
+ sel_getUid("stringWithUTF8String:"),
+ "Parallax wallpaper"));
OBJC_MSG_PTR(window, sel_getUid("makeKeyAndOrderFront:"), nil);
OBJC_MSG_INT(window, sel_getUid("setLevel:"), kCGDesktopWindowLevel - 1);
OBJC_MSG_INT(ns_cfg, sel_getUid("activateIgnoringOthercfgs:"), true);
// Create SDL window from NSWindow
cfg->window = SDL_CreateWindowFrom((void *)window);
- if (cfg->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ if (cfg->window == NULL)
+ lwpLog(LOG_ERROR, "%s", SDL_GetError());
}
#endif
-void initWindow(App *app)
-{
- #ifdef __WIN32
+void initWindow(App *app) {
+#ifdef __WIN32
- app->window =
- SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
- if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ app->window = SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0,
+ SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
+ if (app->window == NULL)
+ lwpLog(LOG_ERROR, "%s", SDL_GetError());
SDL_SysWMinfo sysWmInfo;
SDL_VERSION(&sysWmInfo.version)
@@ -196,84 +88,65 @@ void initWindow(App *app)
HWND hWindow = sysWmInfo.info.win.window;
HWND progman = FindWindow("Progman", NULL);
- iconWorkerw = progman;
+ iconWorkerw = progman;
SendMessageTimeout(progman, 0x052C, NULL, NULL, SMTO_NORMAL, 1000, NULL);
- if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL)) EnumWindows(getIconWorkerw, NULL);
+ if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL))
+ EnumWindows(getIconWorkerw, NULL);
HWND wallpaperWorkerw = GetWindow(iconWorkerw, GW_HWNDNEXT);
SetParent(hWindow, wallpaperWorkerw);
- SetWindowLongPtr(
- hWindow, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE
- );
+ SetWindowLongPtr(hWindow, GWL_EXSTYLE,
+ WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |
+ WS_EX_NOACTIVATE);
SetWindowLongPtr(hWindow, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE);
- SetWindowPos(
- hWindow,
- NULL,
- 0,
- 0,
- GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN),
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW
- );
+ SetWindowPos(hWindow, NULL, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN),
+ GetSystemMetrics(SM_CYVIRTUALSCREEN),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
- #elif __DARWIN
+#elif __DARWIN
- #else
+#else
- if (!app->config.drawOnRootWindow)
- {
+ if (!app->config.drawOnRootWindow) {
Display *display = XOpenDisplay(NULL);
XCloseDisplay(display);
- app->window = SDL_CreateWindow(
- "Layered WallPaper",
- 0,
- 0,
- DisplayWidth(display, 0),
- DisplayHeight(display, 0),
- SDL_WINDOW_OPENGL
- );
+ app->window =
+ SDL_CreateWindow("Layered WallPaper", 0, 0, DisplayWidth(display, 0),
+ DisplayHeight(display, 0), SDL_WINDOW_OPENGL);
SDL_SysWMinfo wmInfo;
SDL_GetVersion(&wmInfo.version);
SDL_GetWindowWMInfo(app->window, &wmInfo);
Window xWnd = wmInfo.info.x11.window;
- display = wmInfo.info.x11.display;
+ display = wmInfo.info.x11.display;
- Atom atomType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", 0);
+ Atom atomType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", 0);
Atom atomDesktop = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", 0);
- XChangeProperty(
- display,
- xWnd,
- atomType,
- XA_ATOM,
- 32,
- PropModeReplace,
- (const unsigned char *)&atomDesktop,
- 1
- );
+ XChangeProperty(display, xWnd, atomType, XA_ATOM, 32, PropModeReplace,
+ (const unsigned char *)&atomDesktop, 1);
Window rootWindow = RootWindow(display, DefaultScreen(display));
XReparentWindow(display, xWnd, rootWindow, 0, 0);
XSync(display, 0);
- }
- else
- {
- Display *display = XOpenDisplay(NULL);
- Window rootWindow = RootWindow(display, DefaultScreen(display));
- app->window = SDL_CreateWindowFrom((void *)rootWindow);
+ } else {
+ Display *display = XOpenDisplay(NULL);
+ Window rootWindow = RootWindow(display, DefaultScreen(display));
+ app->window = SDL_CreateWindowFrom((void *)rootWindow);
XCloseDisplay(display);
}
- #endif
+#endif
- if (app->window == NULL) lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
+ if (app->window == NULL)
+ lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
- app->renderer =
- SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- if (app->renderer == NULL) lwpLog(LOG_ERROR, "Failed to initialize renderer: %s", SDL_GetError());
+ app->renderer = SDL_CreateRenderer(
+ app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (app->renderer == NULL)
+ lwpLog(LOG_ERROR, "Failed to initialize renderer: %s", SDL_GetError());
}
From c08bac599a0c249dcb808660986afc52bdc0893c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Fri, 16 Feb 2024 21:06:30 +0100
Subject: [PATCH 24/36] Tray icon
---
src/core/trayIcon.c | 124 ++++++++++++++++++++++----------------------
1 file changed, 62 insertions(+), 62 deletions(-)
diff --git a/src/core/trayIcon.c b/src/core/trayIcon.c
index 1b17ac0..52b9764 100644
--- a/src/core/trayIcon.c
+++ b/src/core/trayIcon.c
@@ -1,63 +1,63 @@
-#ifdef __WIN32
-
-#include "main.h"
-
-#include
-#include
-#include
-
-
-#define WM_TRAY_ICON (WM_USER + 1)
-
-static NOTIFYICONDATA nid;
-
-void removeTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid); }
-
-int updateTrayIcon() {
- MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return 1;
-}
-
-static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam) {
- switch (uMsg) {
- case WM_TRAY_ICON:
- if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN) {
- gtk_widget_set_visible(mainWnd, 1);
- }
- break;
- }
-}
-
-void initTrayIcon() {
- // Create an invisible window to process tray icon events
-
- HINSTANCE hInstance = GetModuleHandle(NULL);
- const TCHAR CLASS_NAME[] = TEXT("Hidden Window");
- WNDCLASS wc;
- memset(&wc, 0, sizeof(WNDCLASS));
- wc.lpfnWndProc = wndProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(0, CLASS_NAME, TEXT(""), WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
-
- // Create tray icon
-
- nid.cbSize = sizeof(NOTIFYICONDATA);
- nid.hWnd = hWnd;
- nid.uCallbackMessage = WM_TRAY_ICON;
- nid.hIcon = LoadIcon(hInstance, "ID");
- nid.uFlags = NIF_ICON | NIF_MESSAGE;
-
- Shell_NotifyIcon(NIM_ADD, &nid);
-}
-
+#ifdef __WIN32
+
+#include "main.h"
+
+#include
+#include
+#include
+
+
+#define WM_TRAY_ICON (WM_USER + 1)
+
+static NOTIFYICONDATA nid;
+
+void removeTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid); }
+
+int updateTrayIcon() {
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 1;
+}
+
+static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam) {
+ switch (uMsg) {
+ case WM_TRAY_ICON:
+ if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN) {
+ gtk_widget_set_visible(mainWnd, 1);
+ }
+ break;
+ }
+}
+
+void initTrayIcon() {
+ // Create an invisible window to process tray icon events
+
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+ const TCHAR CLASS_NAME[] = TEXT("Hidden Window");
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof(WNDCLASS));
+ wc.lpfnWndProc = wndProc;
+ wc.hInstance = hInstance;
+ wc.lpszClassName = CLASS_NAME;
+ RegisterClass(&wc);
+ HWND hWnd = CreateWindowEx(0, CLASS_NAME, TEXT(""), WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+
+ // Create tray icon
+
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
+ nid.uCallbackMessage = WM_TRAY_ICON;
+ nid.hIcon = LoadIcon(hInstance, "ID");
+ nid.uFlags = NIF_ICON | NIF_MESSAGE;
+
+ Shell_NotifyIcon(NIM_ADD, &nid);
+}
+
#endif
\ No newline at end of file
From 3fc4a7ae99942959856c911bd7b4e0ea23cc3dcf Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Fri, 16 Feb 2024 22:37:00 +0000
Subject: [PATCH 25/36] Finding paths to different program components
---
src/common.h | 32 ++++++++++-
src/common/config.c | 97 ++++++++++++++++++----------------
src/common/monitorScanner.c | 50 ++++++++++--------
src/common/paths.c | 99 +++++++++++++++++++++++++++++++++++
src/common/wallpaperScanner.c | 58 ++++++++------------
src/core/CMakeLists.txt | 9 ++--
src/core/main.c | 15 +++++-
src/wlp/CMakeLists.txt | 3 +-
src/wlp/debug.c | 13 +----
9 files changed, 257 insertions(+), 119 deletions(-)
create mode 100644 src/common/paths.c
diff --git a/src/common.h b/src/common.h
index 9314584..8e8d092 100644
--- a/src/common.h
+++ b/src/common.h
@@ -12,6 +12,8 @@
#define MONITOR_NAME_MAX 100
#define WALLPAPER_NAME_MAX 100
+#define DEFAULT_LINUX_PREFIX "/usr/local"
+
typedef struct
{
int x;
@@ -63,9 +65,37 @@ typedef struct
int targetFps;
} AppConfig;
-MonitorInfo *scanMonitors(int *count);
+//
+// paths.c
+//
+
+#define APP_DIR_BIN 0
+#define APP_DIR_SHARE 1
+#define APP_DIR_USER_SETTINGS 2
+
+void getAppDir(char *buff, int type);
+
+void getMonitorCfgPath(char *buff, const char *name);
+void getWlpCfgPath(char *buff, const char *dirPath);
+void getAppCfgPath(char *buff);
+void getLogPath(char *buff);
+
+//
+// monitorScanner.c
+//
+
+MonitorInfo *scanMonitors(int *count);
+
+//
+// wallpaperScanner.c
+//
+
WallpaperInfo *scanWallpapers(int *count);
+//
+// config.c
+//
+
void saveMonitorConfig(const char *name, MonitorConfig *mc);
int loadMonitorConfig(const char *name, MonitorConfig *mc);
diff --git a/src/common/config.c b/src/common/config.c
index 259af27..bfd2356 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -5,9 +5,9 @@
#include "../common.h"
#define CONFIG_DEFAULT 0
-#define CONFIG_USER 1
+#define CONFIG_USER 1
-void getMonitorConfigPath(const char *name, char *path) {
+/*void getMonitorConfigPath(const char *name, char *path) {
#ifdef __WIN32
sprintf(path, "%s\\lwp\\monitors\\%s.cfg", g_get_user_data_dir(), name);
#else
@@ -15,11 +15,11 @@ void getMonitorConfigPath(const char *name, char *path) {
#endif
}
-void getWallpaperConfigPath(const char *dirName, char *path, int type) {
+void getWallpaperConfigPath(const char *dirPath, char *path, int type) {
if (type == CONFIG_DEFAULT)
- sprintf(path, "%s/wallpaper.cfg", dirName);
+ sprintf(path, "%s/wallpaper.cfg", dirPath);
else
- sprintf(path, "%s/wallpaper.cfg", dirName);
+ sprintf(path, "%s/wallpaper.cfg", dirPath);
}
void getAppConfigPath(char *path, int type) {
@@ -34,9 +34,10 @@ void getAppConfigPath(char *path, int type) {
else
sprintf(path, "%s/.config/lwp/lwp.cfg", g_get_home_dir());
#endif
-}
+}*/
-static void generateEmptyMonitorConfig(MonitorConfig *mc) {
+static void generateEmptyMonitorConfig(MonitorConfig *mc)
+{
sprintf(mc->wlpName, "");
mc->wlpBounds.x = 0;
mc->wlpBounds.y = 0;
@@ -44,8 +45,9 @@ static void generateEmptyMonitorConfig(MonitorConfig *mc) {
mc->wlpBounds.h = 1080;
}
-void saveMonitorConfig(const char *name, MonitorConfig *mc) {
- config_t cfg;
+void saveMonitorConfig(const char *name, MonitorConfig *mc)
+{
+ config_t cfg;
config_setting_t *root, *setting;
config_init(&cfg);
@@ -64,9 +66,10 @@ void saveMonitorConfig(const char *name, MonitorConfig *mc) {
config_setting_set_int(setting, mc->wlpBounds.h);
char path[PATH_MAX];
- getMonitorConfigPath(name, path);
+ getMonitorCfgPath(path, name);
- if (!config_write_file(&cfg, path)) {
+ if (!config_write_file(&cfg, path))
+ {
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
}
@@ -74,36 +77,37 @@ void saveMonitorConfig(const char *name, MonitorConfig *mc) {
config_destroy(&cfg);
}
-int loadMonitorConfig(const char *name, MonitorConfig *mc) {
+int loadMonitorConfig(const char *name, MonitorConfig *mc)
+{
mc->loaded = 0;
- config_t cfg;
+ config_t cfg;
config_setting_t *root, *setting;
char path[PATH_MAX];
- getMonitorConfigPath(name, path);
+ getMonitorCfgPath(path, name);
- if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) {
+ if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS))
+ {
generateEmptyMonitorConfig(mc);
saveMonitorConfig(name, mc);
return 1;
}
config_init(&cfg);
- if (config_read_file(&cfg, path) == CONFIG_FALSE)
- return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
root = config_root_setting(&cfg);
setting = config_setting_get_member(root, "wlpName");
strcpy(mc->wlpName, config_setting_get_string(setting));
- setting = config_setting_get_member(root, "x");
+ setting = config_setting_get_member(root, "x");
mc->wlpBounds.x = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "y");
+ setting = config_setting_get_member(root, "y");
mc->wlpBounds.y = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "w");
+ setting = config_setting_get_member(root, "w");
mc->wlpBounds.w = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "h");
+ setting = config_setting_get_member(root, "h");
mc->wlpBounds.h = config_setting_get_int(setting);
config_destroy(&cfg);
@@ -112,26 +116,27 @@ int loadMonitorConfig(const char *name, MonitorConfig *mc) {
return 1;
}
-int loadAppConfig(AppConfig *ac) {
- config_t cfg;
+int loadAppConfig(AppConfig *ac)
+{
+ config_t cfg;
config_setting_t *root, *setting;
char path[PATH_MAX];
- getAppConfigPath(path, CONFIG_USER);
+ getAppCfgPath(path);
config_init(&cfg);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) {
- getAppConfigPath(path, CONFIG_DEFAULT);
- if (config_read_file(&cfg, path) == CONFIG_FALSE)
- return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ {
+ // todo: set default config values
+ return 0;
}
root = config_root_setting(&cfg);
#ifdef __LINUX
- setting = config_setting_get_member(root, "draw_on_rootwindow");
+ setting = config_setting_get_member(root, "draw_on_rootwindow");
ac->drawOnRootWindow = config_setting_get_int(setting);
#endif
- setting = config_setting_get_member(root, "target_fps");
+ setting = config_setting_get_member(root, "target_fps");
ac->targetFps = config_setting_get_int(setting);
config_destroy(&cfg);
@@ -139,39 +144,41 @@ int loadAppConfig(AppConfig *ac) {
return 1;
}
-int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc) {
+int loadWallpaperConfig(const char *dirPath, WallpaperConfig *wc)
+{
wc->loaded = 0;
- config_t cfg;
+ config_t cfg;
config_setting_t *root, *setting;
config_init(&cfg);
char path[PATH_MAX];
- getWallpaperConfigPath(dirName, path, CONFIG_USER);
+ getWlpCfgPath(path, dirPath);
- if (config_read_file(&cfg, path) == CONFIG_FALSE) {
- getWallpaperConfigPath(dirName, path, CONFIG_DEFAULT);
- if (config_read_file(&cfg, path) == CONFIG_FALSE)
- return 0;
+ if (config_read_file(&cfg, path) == CONFIG_FALSE)
+ {
+ getWlpCfgPath(path, dirPath);
+ if (config_read_file(&cfg, path) == CONFIG_FALSE) return 0;
}
root = config_root_setting(&cfg);
- setting = config_setting_get_member(root, "count");
+ setting = config_setting_get_member(root, "count");
wc->layersCount = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "repeat_x");
- wc->repeatX = config_setting_get_int(setting);
- setting = config_setting_get_member(root, "repeat_y");
- wc->repeatY = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_x");
+ wc->repeatX = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "repeat_y");
+ wc->repeatY = config_setting_get_int(setting);
wc->layerConfigs = malloc(wc->layersCount * sizeof(LayerConfig));
- setting = config_setting_get_member(root, "movement_x");
+ setting = config_setting_get_member(root, "movement_x");
float movX = config_setting_get_float(setting);
- setting = config_setting_get_member(root, "movement_y");
+ setting = config_setting_get_member(root, "movement_y");
float movY = config_setting_get_float(setting);
- for (int i = 0; i < wc->layersCount; i++) {
+ for (int i = 0; i < wc->layersCount; i++)
+ {
LayerConfig *lc = wc->layerConfigs + i;
lc->sensitivityX = movX * i;
diff --git a/src/common/monitorScanner.c b/src/common/monitorScanner.c
index 39882a7..dac0208 100644
--- a/src/common/monitorScanner.c
+++ b/src/common/monitorScanner.c
@@ -13,8 +13,8 @@
#ifdef __WIN32
int monitorEnumIndex = 0;
-static BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect,
- LPARAM param) {
+static BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM param)
+{
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
@@ -22,12 +22,17 @@ static BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect,
MonitorInfo *mi = (MonitorInfo *)param + monitorEnumIndex;
- snprintf(mi->name, MONITOR_NAME_MAX, "Monitor %d%s", monitorEnumIndex + 1,
- info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : "");
- mi->bounds.x = info.rcWork.left;
- mi->bounds.y = info.rcWork.top;
- mi->bounds.w = info.rcWork.right - info.rcWork.left;
- mi->bounds.h = info.rcWork.bottom - info.rcWork.top;
+ snprintf(
+ mi->name,
+ MONITOR_NAME_MAX,
+ "Monitor %d%s",
+ monitorEnumIndex + 1,
+ info.dwFlags == MONITORINFOF_PRIMARY ? " (main)" : ""
+ );
+ mi->bounds.x = info.rcWork.left;
+ mi->bounds.y = info.rcWork.top;
+ mi->bounds.w = info.rcWork.right - info.rcWork.left;
+ mi->bounds.h = info.rcWork.bottom - info.rcWork.top;
mi->config.loaded = 0;
monitorEnumIndex++;
@@ -35,31 +40,34 @@ static BOOL monitorenumproc(HMONITOR monitor, HDC hdc, LPRECT rect,
}
#endif
-MonitorInfo *scanMonitors(int *count) {
+MonitorInfo *scanMonitors(int *count)
+{
MonitorInfo *m = NULL;
#ifdef __WIN32
monitorEnumIndex = 0;
- *count = GetSystemMetrics(SM_CMONITORS);
- m = malloc(sizeof(MonitorInfo) * (*count));
+ *count = GetSystemMetrics(SM_CMONITORS);
+ m = malloc(sizeof(MonitorInfo) * (*count));
EnumDisplayMonitors(NULL, NULL, &monitorenumproc, (LPARAM)m);
#else
- Display *display = XOpenDisplay((getenv("DISPLAY")));
- Window wnd = DefaultRootWindow(display);
- XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
+ int monitorCount;
+
+ Display *display = XOpenDisplay((getenv("DISPLAY")));
+ Window wnd = DefaultRootWindow(display);
+ XRRMonitorInfo *info = XRRGetMonitors(display, wnd, 0, &monitorCount);
m = malloc(sizeof(MonitorInfo) * monitorCount);
int i = 0;
- while (i < monitorCount) {
- snprintf(m[i].name, MONITOR_NAME_MAX, "%s",
- XGetAtomName(display, info->name));
- m[i].bounds.x = info->x;
- m[i].bounds.y = info->y;
- m[i].bounds.w = info->width;
- m[i].bounds.h = info->height;
+ while (i < monitorCount)
+ {
+ snprintf(m[i].name, MONITOR_NAME_MAX, "%s", XGetAtomName(display, info->name));
+ m[i].bounds.x = info->x;
+ m[i].bounds.y = info->y;
+ m[i].bounds.w = info->width;
+ m[i].bounds.h = info->height;
m[i].config.loaded = 0;
info++;
diff --git a/src/common/paths.c b/src/common/paths.c
new file mode 100644
index 0000000..2f5c502
--- /dev/null
+++ b/src/common/paths.c
@@ -0,0 +1,99 @@
+#include
+#include
+#include
+#include
+
+#include "../common.h"
+
+static void removeLastPathEntry(char *path)
+{
+ char *ptr = path + strlen(path) - 1;
+ while (*ptr != '\\') ptr--;
+ *ptr = '\0';
+}
+
+void getAppDir(char *buff, int type)
+{
+#ifdef __LINUX
+
+ char prefix[PATH_MAX];
+
+ char *prefixEnv = getenv("LWP_PREFIX");
+ strcpy(prefix, prefixEnv ? prefixEnv : DEFAULT_LINUX_PREFIX);
+
+#endif
+
+ if (type == APP_DIR_USER_SETTINGS)
+ {
+#ifdef __LINUX
+ sprintf(buff, "%s/.config/lwp", g_get_home_dir());
+#elif __WIN32
+ sprintf(buff, "%s\\lwp", g_get_user_data_dir());
+#endif
+ }
+
+#ifdef __LINUX
+ if (type == APP_DIR_BIN)
+ {
+ sprintf(buff, "%s/%s", prefix, "bin");
+ }
+ else if (type == APP_DIR_SHARE)
+ {
+ sprintf(buff, "%s/%s", prefix, "share/lwp");
+ }
+#elif __WIN32
+ GetModuleFileNameA(NULL, buff, PATH_MAX);
+ removeLastPathEntry(buff);
+#elif __DARWIN
+#endif
+}
+
+void getMonitorCfgPath(char *buff, const char *name)
+{
+ getAppDir(buff, APP_DIR_USER_SETTINGS);
+
+#ifdef __WIN32
+ const char *format = "%s\\monitors\\%s.cfg";
+#else
+ const char *format = "%s/monitors/%s.cfg";
+#endif
+
+ sprintf(buff, format, buff, name);
+}
+
+void getWlpCfgPath(char *buff, const char *dirPath)
+{
+#ifdef __WIN32
+ const char *format = "%s\\wallpaper.cfg";
+#else
+ const char *format = "%s/wallpaper.cfg";
+#endif
+
+ sprintf(buff, format, dirPath);
+}
+
+void getAppCfgPath(char *buff)
+{
+ getAppDir(buff, APP_DIR_USER_SETTINGS);
+
+#ifdef __WIN32
+ const char *format = "%s\\lwp.cfg";
+#else
+ const char *format = "%s/lwp.cfg";
+#endif
+
+ sprintf(buff, format, buff);
+}
+
+void getLogPath(char *buff)
+{
+ getAppDir(buff, APP_DIR_USER_SETTINGS);
+
+#ifdef __WIN32
+ const char *format = "%s\\log.txt";
+#else
+ const char *format = "%s/log";
+#endif
+
+ sprintf(buff, format, buff);
+}
diff --git a/src/common/wallpaperScanner.c b/src/common/wallpaperScanner.c
index 981b128..c45f60e 100644
--- a/src/common/wallpaperScanner.c
+++ b/src/common/wallpaperScanner.c
@@ -4,74 +4,62 @@
#include "../common.h"
#define WALLPAPERS_SYSTEM 0
-#define WALLPAPERS_USER 1
+#define WALLPAPERS_USER 1
+
+WallpaperInfo *scanWallpapers(int *count)
+{
+ *count = 0;
-static void getWallpapersDirPath(char *path, int type) {
#ifdef __WIN32
- if (type == WALLPAPERS_USER)
- sprintf(path, "%s\\lwp\\wallpapers", g_get_user_data_dir());
- else {
- char currentDirPath[PATH_MAX];
- GetModuleFileNameA(NULL, currentDirPath, PATH_MAX);
- char *ptr = currentDirPath+strlen(currentDirPath)-1;
- while(*ptr != '\\')
- ptr--;
- *ptr = '\0';
- sprintf(path, "%s\\wallpapers", currentDirPath);
- }
+ const char *format = "%s\\%s";
#else
- if (type == WALLPAPERS_USER)
- sprintf(path, "%s/.config/lwp/wallpapers", g_get_home_dir());
- else
- sprintf(path, "/usr/local/share/lwp/wallpapers");
+ const char *format = "%s/%s";
#endif
-}
-
-WallpaperInfo *scanWallpapers(int *count) {
- *count = 0;
char userWlpPath[PATH_MAX];
- getWallpapersDirPath(userWlpPath, WALLPAPERS_USER);
+ getAppDir(userWlpPath, APP_DIR_USER_SETTINGS);
+ sprintf(userWlpPath, format, userWlpPath, "wallpapers");
+
char systemWlpPath[PATH_MAX];
- getWallpapersDirPath(systemWlpPath, WALLPAPERS_SYSTEM);
+ getAppDir(systemWlpPath, APP_DIR_SHARE);
+ sprintf(systemWlpPath, format, systemWlpPath, "wallpapers");
- GDir *dir;
- GError *error;
+ GDir *dir;
+ GError *error;
const gchar *filename;
dir = g_dir_open(systemWlpPath, 0, &error);
- while ((g_dir_read_name(dir)))
- (*count)++;
+ while ((g_dir_read_name(dir))) (*count)++;
dir = g_dir_open(userWlpPath, 0, &error);
- while ((g_dir_read_name(dir)))
- (*count)++;
+ while ((g_dir_read_name(dir))) (*count)++;
WallpaperInfo *list = malloc(sizeof(WallpaperInfo) * (*count));
- WallpaperInfo *ptr = list;
+ WallpaperInfo *ptr = list;
dir = g_dir_open(systemWlpPath, 0, &error);
- while ((filename = g_dir_read_name(dir))) {
+ while ((filename = g_dir_read_name(dir)))
+ {
sprintf(ptr->name, "%s", filename);
#ifdef __WIN32
sprintf(ptr->dirPath, "%s\\%s", systemWlpPath, filename);
-
#else
sprintf(ptr->dirPath, "%s/%s", systemWlpPath, filename);
#endif
- ptr->isDefault = 1;
+ ptr->isDefault = 1;
ptr->config.loaded = 0;
ptr++;
}
dir = g_dir_open(userWlpPath, 0, &error);
- while ((filename = g_dir_read_name(dir))) {
+ while ((filename = g_dir_read_name(dir)))
+ {
sprintf(ptr->name, "%s", filename);
#ifdef __WIN32
sprintf(ptr->dirPath, "%s\\%s", userWlpPath, filename);
#else
sprintf(ptr->dirPath, "%s/%s", userWlpPath, filename);
#endif
- ptr->isDefault = 0;
+ ptr->isDefault = 0;
ptr->config.loaded = 0;
ptr++;
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cc0a414..3d3fb22 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,12 +1,13 @@
set(_SOURCE_FILES
+ ../common/paths.c
+ ../common/config.c
+ ../common/wallpaperScanner.c
+ ../common/monitorScanner.c
main.c
windowHandlers.c
wlp.c
trayIcon.c
- ../common/monitorScanner.c
- ../common/config.c
- ../common/wallpaperScanner.c
- )
+)
# Windows resource file
if(_UNAME STREQUAL "WIN32")
diff --git a/src/core/main.c b/src/core/main.c
index 8514ce4..e50d34f 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -64,7 +64,16 @@ static void activate(GtkApplication *app, gpointer userdata)
{
alreadyRunning = 1;
- builder = gtk_builder_new_from_file(MAIN_WINDOW_TEMPLATE_PATH);
+ char gladefilePath[PATH_MAX];
+ getAppDir(gladefilePath, APP_DIR_SHARE);
+#ifdef __WIN32
+ const char *format = "%s\\window_templates\\main.glade";
+#else
+ const char *format = "%s/window_templates/main.glade";
+#endif
+ sprintf(gladefilePath, format, gladefilePath);
+
+ builder = gtk_builder_new_from_file(gladefilePath);
gtk_builder_connect_signals(builder, NULL);
mainWnd = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow");
@@ -103,14 +112,18 @@ int main(int argc, char *argv[])
{
int status;
+#ifdef __WIN32
initTrayIcon();
+#endif
app = gtk_application_new("com.github.jszczerbinsky.lwp", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
+#ifdef __WIN32
removeTrayIcon();
+#endif
return status;
}
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 6e03f2d..13df9ba 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -3,8 +3,9 @@ if(SDL2_RUNTIME_DIR)
endif()
set(_SOURCE_FILES
- ../common/monitorScanner.c
+ ../common/paths.c
../common/config.c
+ ../common/monitorScanner.c
../common/wallpaperScanner.c
main.c
debug.c
diff --git a/src/wlp/debug.c b/src/wlp/debug.c
index d8b15c3..5e51f3a 100644
--- a/src/wlp/debug.c
+++ b/src/wlp/debug.c
@@ -1,22 +1,13 @@
+#include
#include
#include
-#include
#include "main.h"
-void getLogFilePath(char *path)
-{
- #ifdef __WIN32
- sprintf(path, "%s\\lwp\\lwp.log", g_get_user_data_dir());
- #else
- sprintf(path, "/home/cziken/.config/lwp/log");
- #endif
-}
-
void lwpLog(int type, const char *str, ...)
{
char path[PATH_MAX];
- getLogFilePath(path);
+ getLogPath(path);
FILE *file = fopen(path, "a");
From fd39c4052a9b6476967cf34767d2a0e13c71c02c Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sat, 17 Feb 2024 13:49:00 +0000
Subject: [PATCH 26/36] New window template
---
src/core/main.c | 38 +-
src/core/windowHandlers.c | 4 +-
.../assets/cross-close-svgrepo-com.svg | 7 +
.../assets/github-svgrepo-com.svg | 7 +
.../assets/image-photo-svgrepo-com.svg | 7 +
.../assets/question-svgrepo-com.svg | 7 +
.../assets/screen-monitor-svgrepo-com.svg | 7 +
.../assets/settings-svgrepo-com.svg | 10 +
src/window_templates/main.glade | 446 ++++++++++++++----
9 files changed, 445 insertions(+), 88 deletions(-)
create mode 100644 src/window_templates/assets/cross-close-svgrepo-com.svg
create mode 100644 src/window_templates/assets/github-svgrepo-com.svg
create mode 100644 src/window_templates/assets/image-photo-svgrepo-com.svg
create mode 100644 src/window_templates/assets/question-svgrepo-com.svg
create mode 100644 src/window_templates/assets/screen-monitor-svgrepo-com.svg
create mode 100644 src/window_templates/assets/settings-svgrepo-com.svg
diff --git a/src/core/main.c b/src/core/main.c
index e50d34f..8121afb 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -40,6 +40,17 @@ static void reloadMonitorListBox()
g_list_free(rows);
+ char iconPath[PATH_MAX];
+ getAppDir(iconPath, APP_DIR_SHARE);
+#ifdef __WIN32
+ const char *format = "%s\\%s\\%s\\%s";
+#else
+ const char *format = "%s/%s/%s/%s";
+#endif
+ sprintf(
+ iconPath, format, iconPath, "window_templates", "assets", "screen-monitor-svgrepo-com.svg"
+ );
+
int monitorsCount;
MonitorInfo *monitors;
@@ -47,11 +58,32 @@ static void reloadMonitorListBox()
for (int i = 0; i < monitorsCount; i++)
{
- GtkWidget *label = gtk_label_new(monitors[i].name);
- GtkWidget *row = gtk_list_box_row_new();
- gtk_container_add(GTK_CONTAINER(row), label);
+ char resStr[12];
+ sprintf(resStr, "%dx%d", monitors[i].bounds.w, monitors[i].bounds.h);
+
+ GtkWidget *nameLabel = gtk_label_new(monitors[i].name);
+ GtkWidget *resLabel = gtk_label_new(resStr);
+ GtkWidget *icon = gtk_image_new_from_file(iconPath);
+
+ GtkWidget *labelBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add(GTK_CONTAINER(labelBox), nameLabel);
+ gtk_container_add(GTK_CONTAINER(labelBox), resLabel);
+ gtk_box_set_child_packing(GTK_BOX(labelBox), nameLabel, 1, 1, 0, GTK_PACK_START);
+
+ GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_container_add(GTK_CONTAINER(box), icon);
+ gtk_container_add(GTK_CONTAINER(box), labelBox);
+ gtk_box_set_child_packing(GTK_BOX(box), labelBox, 1, 1, 0, GTK_PACK_START);
+
+ GtkWidget *row = gtk_list_box_row_new();
+ gtk_container_add(GTK_CONTAINER(row), box);
gtk_list_box_insert(GTK_LIST_BOX(monitorListBox), row, 0);
+
+ char *nameBuff = malloc(sizeof(strlen(monitors[i].name)));
+ strcpy(nameBuff, monitors[i].name);
+ g_object_set_data(G_OBJECT(row), "monitor_name", (gpointer)nameBuff);
+
gtk_widget_show_all(row);
}
}
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index bba23ab..4e58732 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -71,10 +71,8 @@ G_MODULE_EXPORT void MonitorWindowShow()
// Find selected monitor name
GtkListBoxRow *listBoxRow = gtk_list_box_get_selected_row(GTK_LIST_BOX(monitorListBox));
- GList *children = gtk_container_get_children(GTK_CONTAINER(listBoxRow));
- const char *monitorName = gtk_label_get_label(GTK_LABEL(children->data));
+ const char *monitorName = g_object_get_data(G_OBJECT(listBoxRow), "monitor_name");
gtk_label_set_text(GTK_LABEL(monitorNameLabel), monitorName);
- g_list_free(children);
// Read configuration from config file
MonitorConfig mc;
diff --git a/src/window_templates/assets/cross-close-svgrepo-com.svg b/src/window_templates/assets/cross-close-svgrepo-com.svg
new file mode 100644
index 0000000..a2846fe
--- /dev/null
+++ b/src/window_templates/assets/cross-close-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/assets/github-svgrepo-com.svg b/src/window_templates/assets/github-svgrepo-com.svg
new file mode 100644
index 0000000..c0a813f
--- /dev/null
+++ b/src/window_templates/assets/github-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/assets/image-photo-svgrepo-com.svg b/src/window_templates/assets/image-photo-svgrepo-com.svg
new file mode 100644
index 0000000..a924c43
--- /dev/null
+++ b/src/window_templates/assets/image-photo-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/assets/question-svgrepo-com.svg b/src/window_templates/assets/question-svgrepo-com.svg
new file mode 100644
index 0000000..b29ae56
--- /dev/null
+++ b/src/window_templates/assets/question-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/assets/screen-monitor-svgrepo-com.svg b/src/window_templates/assets/screen-monitor-svgrepo-com.svg
new file mode 100644
index 0000000..439637c
--- /dev/null
+++ b/src/window_templates/assets/screen-monitor-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/assets/settings-svgrepo-com.svg b/src/window_templates/assets/settings-svgrepo-com.svg
new file mode 100644
index 0000000..be067f1
--- /dev/null
+++ b/src/window_templates/assets/settings-svgrepo-com.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index e91fcd9..c7c666d 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -2,9 +2,14 @@
+
False
+ Closing Layered WallPaper
False
+ 480
+ 100
+ assets/question-svgrepo-com.svg
dialog
False
@@ -53,13 +58,36 @@
-
+
True
False
- Are you sure, you want to exit Layered WallPaper?
+
+
+ True
+ False
+ assets/question-svgrepo-com.svg
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Are you sure, you want to close Layered WallPaper?
+
+
+ False
+ True
+ 1
+
+
- False
+ True
True
1
@@ -74,6 +102,7 @@
False
+ Layered WallPaper Settings
False
800
600
@@ -82,6 +111,8 @@
True
False
+ 40
+ 40
vertical
@@ -98,6 +129,7 @@
center
+
@@ -112,6 +144,9 @@
False
Enhance your desktop experiance
center
+
+
+
False
@@ -130,54 +165,306 @@
True
False
- 120
- 120
- 8
- vertical
+ 30
-
+
True
False
- 5
- 5
- Setup your monitors
-
-
-
+ 40
+ 40
+ vertical
+
+
+ True
+ False
+ 5
+ 15
+ Setup your monitors
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ True
+ True
+
+
+ True
+ False
+
+
+ True
+ False
+ 10
+ assets/screen-monitor-svgrepo-com.svg
+ 6
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ HDMI-1
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ 1920x1080
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+
+
+ True
+ True
+
+
+ True
+ False
+
+
+ True
+ False
+ 10
+ assets/screen-monitor-svgrepo-com.svg
+ 6
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ HDMI-1
+
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ 1920x1080
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ Edit settings
+ True
+ True
+ True
+ 10
+
+
+
+ False
+ True
+ 2
+
+
- False
+ True
True
0
-
+
True
False
- 40
- 40
+ center
+ vertical
+ 10
+
+
+ True
+ True
+ True
+
+
+
+ True
+ False
+ vertical
+ True
+
+
+ True
+ False
+ 20
+ assets/image-photo-svgrepo-com.svg
+ 6
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ Manage
+wallpapers
+ center
+
+
+ False
+ True
+ end
+ 1
+
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+
+
+
+ True
+ False
+ vertical
+ True
+
+
+ True
+ False
+ 20
+ assets/cross-close-svgrepo-com.svg
+ 6
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ Turn off
+Layered WallPaper
+ center
+
+
+ False
+ True
+ end
+ 1
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
False
True
+ end
1
-
-
- Edit settings
- True
- True
- True
-
-
-
- False
- True
- 2
-
-
True
@@ -189,6 +476,7 @@
True
False
+ 20
True
@@ -215,7 +503,7 @@
False
True
end
- 2
+ 1
@@ -226,52 +514,15 @@
2
-
-
- True
- False
- center
-
-
- Manage wallpapers
- True
- True
- True
-
-
-
- False
- True
- 0
-
-
-
-
- Exit
- True
- True
- True
-
-
-
- False
- True
- end
- 1
-
-
-
-
- False
- True
- 3
-
-
False
+ Wallpaper Manager
+ 800
+ 600
+ assets/image-photo-svgrepo-com.svg
@@ -368,6 +619,10 @@
False
+ Monitor Settings
+ 600
+ 260
+ assets/settings-svgrepo-com.svg
@@ -376,16 +631,40 @@
False
vertical
-
+
True
False
- 10
- 10
- Monitor name
- center
-
-
-
+ center
+
+
+ True
+ False
+ assets/screen-monitor-svgrepo-com.svg
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 10
+ 10
+ Monitor name
+ center
+
+
+
+
+
+ False
+ True
+ 1
+
+
False
@@ -538,6 +817,9 @@
False
center
20
+ 20
+ 50
+ True
Apply
From 26073474aabb35db3dceda581696996e89f475f3 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Sun, 18 Feb 2024 21:15:03 +0000
Subject: [PATCH 27/36] Application settings window and wallpaper filtering
---
src/common.h | 8 +-
src/common/config.c | 71 +++++----
src/core/main.c | 46 +++---
src/core/main.h | 4 +
src/core/windowHandlers.c | 36 +++++
src/window_templates/main.glade | 262 +++++++++++++++++++++++++++++++-
src/wlp/main.c | 1 +
7 files changed, 369 insertions(+), 59 deletions(-)
diff --git a/src/common.h b/src/common.h
index 8e8d092..8dc09b2 100644
--- a/src/common.h
+++ b/src/common.h
@@ -61,8 +61,9 @@ typedef struct
typedef struct
{
- int drawOnRootWindow;
- int targetFps;
+ int drawOnRootWindow;
+ int targetFps;
+ char renderQuality[8];
} AppConfig;
//
@@ -99,7 +100,8 @@ WallpaperInfo *scanWallpapers(int *count);
void saveMonitorConfig(const char *name, MonitorConfig *mc);
int loadMonitorConfig(const char *name, MonitorConfig *mc);
-int loadAppConfig(AppConfig *ac);
+int loadAppConfig(AppConfig *ac);
+void saveAppConfig(AppConfig *ac);
int loadWallpaperConfig(const char *dirName, WallpaperConfig *wc);
diff --git a/src/common/config.c b/src/common/config.c
index bfd2356..0ede3a3 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -7,35 +7,6 @@
#define CONFIG_DEFAULT 0
#define CONFIG_USER 1
-/*void getMonitorConfigPath(const char *name, char *path) {
-#ifdef __WIN32
- sprintf(path, "%s\\lwp\\monitors\\%s.cfg", g_get_user_data_dir(), name);
-#else
- sprintf(path, "%s/.config/lwp/monitors/%s.cfg", g_get_home_dir(), name);
-#endif
-}
-
-void getWallpaperConfigPath(const char *dirPath, char *path, int type) {
- if (type == CONFIG_DEFAULT)
- sprintf(path, "%s/wallpaper.cfg", dirPath);
- else
- sprintf(path, "%s/wallpaper.cfg", dirPath);
-}
-
-void getAppConfigPath(char *path, int type) {
-#ifdef __WIN32
- if (type == CONFIG_DEFAULT)
- sprintf(path, "/etc/lwp.cfg");
- else
- sprintf(path, "%s\\lwp\\lwp.cfg", g_get_user_data_dir());
-#else
- if (type == CONFIG_DEFAULT)
- sprintf(path, "/etc/lwp.cfg");
- else
- sprintf(path, "%s/.config/lwp/lwp.cfg", g_get_home_dir());
-#endif
-}*/
-
static void generateEmptyMonitorConfig(MonitorConfig *mc)
{
sprintf(mc->wlpName, "");
@@ -116,6 +87,42 @@ int loadMonitorConfig(const char *name, MonitorConfig *mc)
return 1;
}
+static void useDefaultAppCfg(AppConfig *ac)
+{
+#ifdef __LINUX
+ ac->drawOnRootWindow = 0;
+#endif
+ ac->targetFps = 60;
+ strcpy(ac->renderQuality, "best");
+}
+
+void saveAppConfig(AppConfig *ac)
+{
+ config_t cfg;
+ config_setting_t *root, *setting;
+
+ config_init(&cfg);
+ root = config_root_setting(&cfg);
+
+ setting = config_setting_add(root, "draw_on_rootwindow", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, ac->drawOnRootWindow);
+ setting = config_setting_add(root, "target_fps", CONFIG_TYPE_INT);
+ config_setting_set_int(setting, ac->targetFps);
+ setting = config_setting_add(root, "render_quality", CONFIG_TYPE_STRING);
+ config_setting_set_string(setting, ac->renderQuality);
+
+ char path[PATH_MAX];
+ getAppCfgPath(path);
+
+ if (!config_write_file(&cfg, path))
+ {
+ fprintf(stderr, "Error while writing file.\n");
+ config_destroy(&cfg);
+ }
+
+ config_destroy(&cfg);
+}
+
int loadAppConfig(AppConfig *ac)
{
config_t cfg;
@@ -127,8 +134,8 @@ int loadAppConfig(AppConfig *ac)
config_init(&cfg);
if (config_read_file(&cfg, path) == CONFIG_FALSE)
{
- // todo: set default config values
- return 0;
+ useDefaultAppCfg(ac);
+ return 1;
}
root = config_root_setting(&cfg);
@@ -138,6 +145,8 @@ int loadAppConfig(AppConfig *ac)
#endif
setting = config_setting_get_member(root, "target_fps");
ac->targetFps = config_setting_get_int(setting);
+ setting = config_setting_get_member(root, "render_quality");
+ strcpy(ac->renderQuality, config_setting_get_string(setting));
config_destroy(&cfg);
diff --git a/src/core/main.c b/src/core/main.c
index 8121afb..e901b50 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -2,30 +2,26 @@
#include "../platform_guard.h"
-#ifdef __WIN32
-#define MAIN_WINDOW_TEMPLATE_PATH "./window_templates/main.glade"
-#elif __DARWIN
-#define MAIN_WINDOW_TEMPLATE_PATH ""
-#else
-#define MAIN_WINDOW_TEMPLATE_PATH "/usr/local/share/lwp/window_templates/main.glade"
-#endif
-
GtkApplication *app = NULL;
GtkBuilder *builder = NULL;
-GtkWidget *mainWnd = NULL;
-GtkWidget *exitDialog = NULL;
-GtkWidget *wallpaperMgrWnd = NULL;
-GtkWidget *monitorWnd = NULL;
-GtkWidget *monitorListBox = NULL;
-GtkWidget *wallpaperListBox = NULL;
-GtkWidget *wallpaperComboBox = NULL;
-GtkWidget *xPosSpinBtn = NULL;
-GtkWidget *yPosSpinBtn = NULL;
-GtkWidget *widthSpinBtn = NULL;
-GtkWidget *heightSpinBtn = NULL;
-GtkWidget *monitorNameLabel = NULL;
-GtkWidget *versionLabel = NULL;
+GtkWidget *mainWnd = NULL;
+GtkWidget *exitDialog = NULL;
+GtkWidget *wallpaperMgrWnd = NULL;
+GtkWidget *monitorWnd = NULL;
+GtkWidget *monitorListBox = NULL;
+GtkWidget *wallpaperListBox = NULL;
+GtkWidget *wallpaperComboBox = NULL;
+GtkWidget *xPosSpinBtn = NULL;
+GtkWidget *yPosSpinBtn = NULL;
+GtkWidget *widthSpinBtn = NULL;
+GtkWidget *heightSpinBtn = NULL;
+GtkWidget *monitorNameLabel = NULL;
+GtkWidget *versionLabel = NULL;
+GtkWidget *appSettingsWnd = NULL;
+GtkWidget *targetFpsComboBox = NULL;
+GtkWidget *renderQualityComboBox = NULL;
+GtkWidget *drawOnRootWndComboBox = NULL;
static void reloadMonitorListBox()
{
@@ -112,6 +108,7 @@ static void activate(GtkApplication *app, gpointer userdata)
exitDialog = (GtkWidget *)gtk_builder_get_object(builder, "ExitDialog");
wallpaperMgrWnd = (GtkWidget *)gtk_builder_get_object(builder, "WallpaperManagerWindow");
monitorWnd = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow");
+ appSettingsWnd = (GtkWidget *)gtk_builder_get_object(builder, "SettingsWindow");
monitorListBox = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_MonitorListBox");
versionLabel = (GtkWidget *)gtk_builder_get_object(builder, "MainWindow_VersionLabel");
wallpaperListBox =
@@ -124,11 +121,18 @@ static void activate(GtkApplication *app, gpointer userdata)
heightSpinBtn = (GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_HeightSpinBtn");
monitorNameLabel =
(GtkWidget *)gtk_builder_get_object(builder, "MonitorWindow_MonitorNameLabel");
+ targetFpsComboBox =
+ (GtkWidget *)gtk_builder_get_object(builder, "SettingsWindow_TargetFpsComboBox");
+ renderQualityComboBox =
+ (GtkWidget *)gtk_builder_get_object(builder, "SettingsWindow_TexFilteringComboBox");
+ drawOnRootWndComboBox =
+ (GtkWidget *)gtk_builder_get_object(builder, "SettingsWindow_DrawOnRootWndComboBox");
gtk_window_set_application(GTK_WINDOW(mainWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(exitDialog), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(wallpaperMgrWnd), GTK_APPLICATION(app));
gtk_window_set_application(GTK_WINDOW(monitorWnd), GTK_APPLICATION(app));
+ gtk_window_set_application(GTK_WINDOW(appSettingsWnd), GTK_APPLICATION(app));
gtk_label_set_text(GTK_LABEL(versionLabel), PROGRAM_VERSION);
diff --git a/src/core/main.h b/src/core/main.h
index 7b17497..b775e33 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -19,6 +19,10 @@ extern GtkWidget *yPosSpinBtn;
extern GtkWidget *widthSpinBtn;
extern GtkWidget *heightSpinBtn;
extern GtkWidget *monitorNameLabel;
+extern GtkWidget *appSettingsWnd;
+extern GtkWidget *targetFpsComboBox;
+extern GtkWidget *renderQualityComboBox;
+extern GtkWidget *drawOnRootWndComboBox;
void runWlp();
void killWlp();
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index 4e58732..b47a504 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -23,6 +23,8 @@ G_MODULE_EXPORT void MainWindow_MonitorEditBtnClick() { gtk_widget_set_visible(m
G_MODULE_EXPORT void MainWindow_ExitBtnClick() { gtk_widget_set_visible(exitDialog, 1); }
+G_MODULE_EXPORT void MainWindow_AppSettingsBtnClick() { gtk_widget_set_visible(appSettingsWnd, 1); }
+
G_MODULE_EXPORT void MainWindowClose() { gtk_widget_set_visible(mainWnd, 0); }
// Wallpapaer Manager Window handlers
@@ -103,3 +105,37 @@ G_MODULE_EXPORT void MonitorWindow_ApplyBtnClick()
}
G_MODULE_EXPORT void MonitorWindow_ExitBtnClick() { gtk_widget_set_visible(monitorWnd, 0); }
+
+// App Settings Window handlers
+
+G_MODULE_EXPORT void SettingsWindowShow()
+{
+ AppConfig ac;
+ loadAppConfig(&ac);
+
+ char targetFpsStr[4];
+ sprintf(targetFpsStr, "%d", ac.targetFps);
+ char drawOnRootWindowStr[2];
+ sprintf(drawOnRootWindowStr, "%d", ac.drawOnRootWindow);
+
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(renderQualityComboBox), ac.renderQuality);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(targetFpsComboBox), targetFpsStr);
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(drawOnRootWndComboBox), drawOnRootWindowStr);
+}
+
+G_MODULE_EXPORT void SettingsWindowClose() { gtk_widget_set_visible(appSettingsWnd, 0); }
+
+G_MODULE_EXPORT void SettingsWindow_ApplyBtnClick()
+{
+ AppConfig ac;
+ strcpy(ac.renderQuality, gtk_combo_box_get_active_id(GTK_COMBO_BOX(renderQualityComboBox)));
+ ac.targetFps = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(targetFpsComboBox)));
+ ac.drawOnRootWindow = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(drawOnRootWndComboBox)));
+
+ saveAppConfig(&ac);
+
+ killWlp();
+ runWlp();
+}
+
+G_MODULE_EXPORT void SettingsWindow_ExitBtnClick() { gtk_widget_set_visible(appSettingsWnd, 0); }
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index c7c666d..0c9be83 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -368,7 +368,6 @@
True
False
vertical
- True
True
@@ -387,6 +386,8 @@
True
False
+ 15
+ 15
Manage
wallpapers
center
@@ -407,6 +408,57 @@ wallpapers
0
+
+
+ True
+ True
+ True
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ assets/settings-svgrepo-com.svg
+ 6
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ 15
+ 15
+ Application
+settings
+ center
+
+
+ False
+ True
+ end
+ 1
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
True
@@ -418,7 +470,6 @@ wallpapers
True
False
vertical
- True
True
@@ -437,6 +488,8 @@ wallpapers
True
False
+ 15
+ 15
Turn off
Layered WallPaper
center
@@ -454,7 +507,7 @@ Layered WallPaper
False
True
- 1
+ 2
@@ -517,6 +570,207 @@ Layered WallPaper
+
+ False
+ False
+ 500
+ 250
+
+
+
+ True
+ False
+ vertical
+
+
+
+ True
+ False
+ center
+
+
+ True
+ False
+ assets/settings-svgrepo-com.svg
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 10
+ 10
+ Application settings
+ center
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
+ True
+ False
+ 20
+ 20
+ 15
+ True
+ True
+
+
+ True
+ False
+ start
+ Target FPS
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ start
+ Texture filtering
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+
+ - Anisotropic
+ - Linear
+ - Nearest-neighbour
+
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ start
+ Draw on root window (Linux only)
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+
+ - No
+ - Yes
+
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+
+ - 30 fps
+ - 60 fps
+ - 120 fps
+ - 144 fps
+ - 240 fps
+
+
+
+ 1
+ 0
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ center
+ 20
+ 20
+ 50
+ True
+
+
+ Apply
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ Exit
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 2
+
+
+
+
+
False
Wallpaper Manager
@@ -821,7 +1075,7 @@ Layered WallPaper
50
True
-
+
Apply
True
True
diff --git a/src/wlp/main.c b/src/wlp/main.c
index a3c399a..b7c5196 100644
--- a/src/wlp/main.c
+++ b/src/wlp/main.c
@@ -179,6 +179,7 @@ int main(int argc, char *argv[])
lwpLog(LOG_INFO, "Initializing SDL");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, app.config.renderQuality);
lwpLog(LOG_INFO, "Initializing window");
initWindow(&app);
From 5bf368c8b92d60ce173fc98a652fac9baf92a602 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Sun, 18 Feb 2024 22:58:59 +0000
Subject: [PATCH 28/36] Update README.md
---
README.md | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 0869246..54b2e94 100644
--- a/README.md
+++ b/README.md
@@ -25,11 +25,12 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
Linux
-
- #### Installation steps
-
+
+ ### Dependencies
- Install `SDL2` using Your package manager
- If You are using `Wayland`, You also must install `XWayland`
+
+ #### Installation steps
- Download `.tar.gz` package from [releases](https://github.com/jszczerbinsky/lwp/releases/latest)
- Extract the content to `/`:
```shell
@@ -40,8 +41,7 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
- To make Layered WallPaper run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
#### Build from source instead
- - Install `SDL2` using Your package manager. On some distributions `SDL2` doesn't contain development files, so it may be also necessary to install development version of `SDL2`
- - If You are using `Wayland`, You also must install `XWayland`
+ - In some distributions `SDL2` doesn't contain development files, so it may be also necessary to install development version of `SDL2`
- Install `CMake`
- Clone the repository and prepare a `build` directory:
@@ -69,6 +69,9 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
macOS
+
+ ### Dependencies
+ Install the dependencies (homebrew: `brew install sdl2 gtk+3 libconfig`)
#### Installation steps
- Download and run the installer from [releases](https://github.com/jszczerbinsky/lwp/releases/latest)
@@ -77,7 +80,6 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
- To stop running Layered WallPaper on startup, run it again
#### Build from source instead
- - Install `SDL2` (homebrew: `brew install sdl2`)
- To build this project, You need to install `cmake` (homebrew: `brew install cmake`)
- Clone the repository:
```zsh
@@ -269,4 +271,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+SOFTWARE.
From 29912ed54e6d529be50953729fc4c055dd250d46 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Mon, 19 Feb 2024 20:33:39 +0000
Subject: [PATCH 29/36] Creating user settings dirs at startup
---
src/common.h | 2 ++
src/common/paths.c | 19 +++++++++++++++++++
src/core/main.c | 2 ++
3 files changed, 23 insertions(+)
diff --git a/src/common.h b/src/common.h
index 8dc09b2..a827eac 100644
--- a/src/common.h
+++ b/src/common.h
@@ -81,6 +81,8 @@ void getWlpCfgPath(char *buff, const char *dirPath);
void getAppCfgPath(char *buff);
void getLogPath(char *buff);
+void createUserDirs();
+
//
// monitorScanner.c
//
diff --git a/src/common/paths.c b/src/common/paths.c
index 2f5c502..afb5e04 100644
--- a/src/common/paths.c
+++ b/src/common/paths.c
@@ -5,6 +5,25 @@
#include "../common.h"
+void createUserDirs()
+{
+#ifdef __WIN32
+ const char *format = "%s\\%s";
+#else
+ const char *format = "%s/%s";
+#endif
+
+ char path[PATH_MAX];
+
+ getAppDir(path, APP_DIR_USER_SETTINGS);
+ sprintf(path, format, path, "wallpapers");
+ g_mkdir_with_parents(path, 484);
+
+ getAppDir(path, APP_DIR_USER_SETTINGS);
+ sprintf(path, format, path, "monitors");
+ g_mkdir_with_parents(path, 484);
+}
+
static void removeLastPathEntry(char *path)
{
char *ptr = path + strlen(path) - 1;
diff --git a/src/core/main.c b/src/core/main.c
index e901b50..4be7984 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -148,6 +148,8 @@ int main(int argc, char *argv[])
{
int status;
+ createUserDirs();
+
#ifdef __WIN32
initTrayIcon();
#endif
From 6445b631b9709790017cc628222e5b26150c63df Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Tue, 20 Feb 2024 14:11:17 +0000
Subject: [PATCH 30/36] G_APPLICATION_FLAGS_NONE compatibility
---
src/core/main.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/core/main.h b/src/core/main.h
index b775e33..7b9697f 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -3,6 +3,11 @@
#include
+// G_APPLICATION_DEFAULT_FLAGS doesn't exist in older versions of glib
+#ifndef G_APPLICATION_DEFAULT_FLAGS
+#define G_APPLICATION_DEFAULT_FLAGS G_APPLICATION_FLAGS_NONE
+#endif
+
#include "../common.h"
extern GtkApplication *app;
From 14a1ab76301d43b53acf37b9191eda2a5ce1c0cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Fri, 8 Mar 2024 17:44:29 +0000
Subject: [PATCH 31/36] Update build.yml
---
.github/workflows/build.yml | 62 +++++++++++++------------------------
1 file changed, 21 insertions(+), 41 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6a81a7e..689157a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -17,7 +17,7 @@ jobs:
- name: Install cmake
uses: lukka/get-cmake@v3.26.0
- name: Install dependencies
- run: sudo apt install libsdl2-dev
+ run: sudo apt update && sudo apt install libsdl2-dev libconfig-dev libgtk-3-dev
- name: Build
run: mkdir -p build && cd build && cmake ../ && cmake --build . && cpack
@@ -28,45 +28,25 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- - name: Install cmake
- uses: lukka/get-cmake@v3.26.0
- - name: Install MinGW
- uses: egor-tensin/setup-mingw@v2
- - name: Install MSVC
- uses: ilammy/msvc-dev-cmd@v1
- - name: Install wget
- run: choco install wget
- - name: Install dependencies`
- run: |
- wget -nv https://github.com/libsdl-org/SDL/releases/download/release-2.26.3/SDL2-devel-2.26.3-mingw.zip
- 7z x -bd SDL2-devel-2.26.3-mingw.zip -omingw
- wget -nv https://github.com/libsdl-org/SDL/releases/download/release-2.26.3/SDL2-devel-2.26.3-VC.zip
- 7z x -bd SDL2-devel-2.26.3-VC.zip -omsvc
- - name: Build with MSVC
+ - name: Install MSYS2
+ uses: msys2/setup-msys2@v2
+ with:
+ update: true
+ msystem: MINGW64
+ install: >-
+ git
+ curl
+ unzip
+ mingw-w64-x86_64-cmake
+ mingw-w64-x86_64-gcc
+ mingw-w64-x86_64-gtk3
+ mingw-w64-x86_64-SDL2
+ mingw-w64-x86_64-libconfig
+ - name: Download SDL2 runtime
+ shell: msys2 {0}
run: |
- mkdir buildMSVC
- cd buildMSVC
- cmake -G "Visual Studio 17" -DSDL2_DIR=${{ github.workspace }}\msvc\SDL2-2.26.3\cmake -DSDL2_RUNTIME_DIR=${{ github.workspace }}\msvc\SDL2-2.26.3\lib\x64 ..\
- cmake --build .
- cd ..
- - name: Build with MinGW
- run: |
- mkdir buildMinGW
- cd buildMinGW
- cmake -G "MinGW Makefiles" -DSDL2_DIR=${{ github.workspace }}\mingw\SDL2-2.26.3\cmake -DSDL2_RUNTIME_DIR=${{ github.workspace }}\mingw\SDL2-2.26.3\x86_64-mingw32\bin -DCMAKE_BUILD_TYPE=Release ..\
- cmake --build .
-
-
- macOS:
- name: Build on MacOS
- runs-on: macos-12
-
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- - name: Install cmake
- uses: lukka/get-cmake@v3.26.0
- - name: Install dependencies`
- run: brew install sdl2
+ curl -L https://github.com/libsdl-org/SDL/releases/download/release-2.30.1/SDL2-2.30.1-win32-x64.zip > sdl2.zip
+ unzip sdl2.zip
- name: Build
- run: mkdir build && cd build && cmake ../ && cmake --build . && sudo cpack
+ shell: msys2 {0}
+ run: mkdir -p build && cd build && cmake -DSDL2_RUNTIME_DIR=${GITHUB_WORKSPACE} ../ && cmake --build . && ../distributeDLLs.sh && cpack
From 878043a502fabac51e69a4dd550572b67c41f785 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Fri, 8 Mar 2024 18:56:56 +0000
Subject: [PATCH 32/36] Hiding window on start
---
src/core/main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 4be7984..0ecca84 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -90,8 +90,6 @@ static void activate(GtkApplication *app, gpointer userdata)
if (!alreadyRunning)
{
- alreadyRunning = 1;
-
char gladefilePath[PATH_MAX];
getAppDir(gladefilePath, APP_DIR_SHARE);
#ifdef __WIN32
@@ -141,7 +139,9 @@ static void activate(GtkApplication *app, gpointer userdata)
reloadMonitorListBox();
- gtk_widget_set_visible(mainWnd, 1);
+ if (alreadyRunning) gtk_widget_set_visible(mainWnd, 1);
+
+ alreadyRunning = 1;
}
int main(int argc, char *argv[])
From 8ff13a43482886b1d3d954b651f0ff9922725991 Mon Sep 17 00:00:00 2001
From: jszczerbinsky
Date: Fri, 8 Mar 2024 19:29:51 +0000
Subject: [PATCH 33/36] Custom installation prefix on Linux
---
CMakeLists.txt | 46 ++-----------
src/common.h | 2 -
src/common/paths.c | 1 -
src/core/CMakeLists.txt | 9 +--
src/core/trayIcon.c | 65 +++++++++++-------
src/core/wlp.c | 6 +-
src/platform_guard.h | 8 +--
src/wlp/CMakeLists.txt | 16 +----
src/wlp/main.h | 7 --
src/wlp/render.c | 4 --
src/wlp/window.c | 145 +++++++++++++++++-----------------------
11 files changed, 119 insertions(+), 190 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9069ed9..78672fa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,9 +6,7 @@ project(lwp
LANGUAGES C)
# Detect the platform
-if (APPLE)
- set(_UNAME "DARWIN")
-elseif (MSYS OR MINGW)
+if (MSYS OR MINGW)
set(_UNAME "WIN32")
elseif(UNIX)
set(_UNAME "LINUX")
@@ -40,9 +38,6 @@ set(_DEFAULT_CONFIG_FILE default.cfg)
if(_UNAME STREQUAL "WIN32")
set(_DEFAULT_CONFIG_FILE defaultWin.cfg)
endif()
-if (_UNAME STREQUAL "DARWIN")
- set(_DEFAULT_CONFIG_FILE defaultMac.cfg)
-endif()
add_subdirectory(src/wlp)
link_directories(src/wlp)
@@ -60,43 +55,17 @@ if(_UNAME STREQUAL "WIN32")
DESTINATION .)
install(FILES LICENSE.txt
DESTINATION .)
- install(FILES ${_DEFAULT_CONFIG_FILE}
- DESTINATION .)
install(FILES ${SDL2_RUNTIME_DIR}/SDL2.dll
DESTINATION .)
install(FILES ${SDL2_RUNTIME_DIR}/README-SDL.txt
DESTINATION .)
-elseif(_UNAME STREQUAL "LINUX")
+else()
install(DIRECTORY wallpapers
- DESTINATION usr/local/share/lwp)
+ DESTINATION share/lwp)
install(DIRECTORY src/window_templates
- DESTINATION usr/local/share/lwp)
+ DESTINATION share/lwp)
install(FILES LICENSE.txt
- DESTINATION usr/local/share/lwp)
- install(FILES ${_DEFAULT_CONFIG_FILE}
- TYPE SYSCONF
- RENAME lwp.cfg)
-else()
- install(DIRECTORY wallpapers
- DESTINATION Layered_WallPaper)
- install(DIRECTORY src/window_templates
- DESTINATION Layered_WallPaper)
- install(FILES LICENSE.txt
- DESTINATION Layered_WallPaper)
- install(FILES ${_DEFAULT_CONFIG_FILE}
- DESTINATION Layered_WallPaper
- RENAME lwp.cfg)
- install(FILES lwp.template.plist
- DESTINATION Layered_WallPaper)
- install (FILES setupPlist.command
- DESTINATION Layered_WallPaper
- RENAME Toggle_Autorun.command
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
- install (FILES setupPlist.command
- DESTINATION .
- RENAME Toggle_Autorun.command
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
-
+ DESTINATION share/lwp)
endif()
@@ -107,11 +76,8 @@ if (_UNAME STREQUAL "WIN32")
elseif(_UNAME STREQUAL "LINUX")
set(CPACK_GENERATOR TGZ)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
-elseif(_UNAME STREQUAL "DARWIN")
- set(CPACK_GENERATOR DragNDrop)
- set(CPACK_DMG_BACKGROUND_IMAGE ${CMAKE_CURRENT_SOURCE_DIR}/dmgBg.png)
- set(CPACK_DMG_DS_STORE_SETUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/setupDmg.applescript)
endif()
+
set(CPACK_NSIS_MUI_ICON ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico)
set(CPACK_NSIS_MUI_UNIICON ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico)
set(CPACK_NSIS_INSTALLED_ICON_NAME ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico)
diff --git a/src/common.h b/src/common.h
index a827eac..e17526b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -3,8 +3,6 @@
#ifdef __LINUX
#include
-#elif __DARWIN
-#include
#else
#include
#endif
diff --git a/src/common/paths.c b/src/common/paths.c
index afb5e04..e2e79b8 100644
--- a/src/common/paths.c
+++ b/src/common/paths.c
@@ -63,7 +63,6 @@ void getAppDir(char *buff, int type)
#elif __WIN32
GetModuleFileNameA(NULL, buff, PATH_MAX);
removeLastPathEntry(buff);
-#elif __DARWIN
#endif
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3d3fb22..b0eaa33 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -47,9 +47,7 @@ list(APPEND _INCLUDE_DIRS ${libconfig_INCLUDE_DIRS})
list(APPEND _LIBS ${libconfig_LINK_LIBRARIES})
# Main executable
-if (_UNAME STREQUAL "DARWIN")
- add_executable(lwp MACOSX_BUNDLE ${_SOURCE_FILES})
-elseif(_UNAME STREQUAL "WIN32")
+if(_UNAME STREQUAL "WIN32")
add_executable(lwp WIN32 ${_SOURCE_FILES})
else()
add_executable(lwp ${_SOURCE_FILES})
@@ -67,9 +65,6 @@ if(_UNAME STREQUAL "WIN32")
DESTINATION .)
elseif(_UNAME STREQUAL "LINUX")
install(TARGETS lwp
- DESTINATION usr/local/bin)
-else()
- install(TARGETS lwp
- DESTINATION Layered_WallPaper)
+ DESTINATION bin)
endif()
diff --git a/src/core/trayIcon.c b/src/core/trayIcon.c
index 52b9764..b63cdbc 100644
--- a/src/core/trayIcon.c
+++ b/src/core/trayIcon.c
@@ -1,11 +1,10 @@
#ifdef __WIN32
-#include "main.h"
-
#include
#include
#include
+#include "main.h"
#define WM_TRAY_ICON (WM_USER + 1)
@@ -13,9 +12,11 @@ static NOTIFYICONDATA nid;
void removeTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid); }
-int updateTrayIcon() {
+int updateTrayIcon()
+{
MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -23,41 +24,55 @@ int updateTrayIcon() {
return 1;
}
-static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam) {
- switch (uMsg) {
- case WM_TRAY_ICON:
- if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN) {
- gtk_widget_set_visible(mainWnd, 1);
- }
- break;
+static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_TRAY_ICON:
+ if (lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDOWN)
+ {
+ gtk_widget_set_visible(mainWnd, 1);
+ }
+ break;
}
}
-void initTrayIcon() {
+void initTrayIcon()
+{
// Create an invisible window to process tray icon events
- HINSTANCE hInstance = GetModuleHandle(NULL);
+ HINSTANCE hInstance = GetModuleHandle(NULL);
const TCHAR CLASS_NAME[] = TEXT("Hidden Window");
- WNDCLASS wc;
+ WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
- wc.lpfnWndProc = wndProc;
- wc.hInstance = hInstance;
+ wc.lpfnWndProc = wndProc;
+ wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
- HWND hWnd = CreateWindowEx(0, CLASS_NAME, TEXT(""), WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
+ HWND hWnd = CreateWindowEx(
+ 0,
+ CLASS_NAME,
+ TEXT(""),
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ hInstance,
+ NULL
+ );
// Create tray icon
- nid.cbSize = sizeof(NOTIFYICONDATA);
- nid.hWnd = hWnd;
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
nid.uCallbackMessage = WM_TRAY_ICON;
- nid.hIcon = LoadIcon(hInstance, "ID");
- nid.uFlags = NIF_ICON | NIF_MESSAGE;
+ nid.hIcon = LoadIcon(hInstance, "ID");
+ nid.uFlags = NIF_ICON | NIF_MESSAGE;
Shell_NotifyIcon(NIM_ADD, &nid);
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/core/wlp.c b/src/core/wlp.c
index a51aac9..3ba9668 100644
--- a/src/core/wlp.c
+++ b/src/core/wlp.c
@@ -53,7 +53,11 @@ void runWlp()
printf("Failed to start a wallpaper subprocess");
#else
- wlpProcess = popen("/usr/local/bin/lwpwlp", "r");
+ char path[PATH_MAX];
+ getAppDir(path, APP_DIR_BIN);
+ strcat(path, "/lwpwlp");
+
+ wlpProcess = popen(path, "r");
char buff[10];
fgets(buff, sizeof(buff) - 1, wlpProcess);
wlpPid = atoi(buff);
diff --git a/src/platform_guard.h b/src/platform_guard.h
index 23b647c..2b1dda8 100644
--- a/src/platform_guard.h
+++ b/src/platform_guard.h
@@ -2,13 +2,11 @@
#define PLATFORM_GUARD_H
#ifndef __WIN32
-#ifndef __DARWIN
#ifndef __LINUX
#error "Unsupported platform."
-#endif // __LINUX
-#endif // __DARWIN
-#endif // __WIN32
+#endif // __LINUX
+#endif // __WIN32
-#endif // PLATFORM_GUARD_H
+#endif // PLATFORM_GUARD_H
diff --git a/src/wlp/CMakeLists.txt b/src/wlp/CMakeLists.txt
index 13df9ba..8055a49 100644
--- a/src/wlp/CMakeLists.txt
+++ b/src/wlp/CMakeLists.txt
@@ -40,11 +40,6 @@ find_package(SDL2 REQUIRED CONFIG)
list(APPEND _INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
list(APPEND _LIBS ${SDL2_LIBRARIES})
-if (_UNAME STREQUAL "DARWIN")
- # MacOSX framework dependencies
- list(APPEND _LIBS "-framework CoreGraphics" "-framework Foundation")
-endif()
-
if (_UNAME STREQUAL "LINUX")
# X11 dependency
find_package(X11 REQUIRED)
@@ -55,9 +50,7 @@ endif()
option(LWP_INSTALL_LAUNCHD "Launch lwp on login (MacOSX only)" OFF)
# Main executable
-if (_UNAME STREQUAL "DARWIN")
- add_executable(lwpwlp MACOSX_BUNDLE ${_SOURCE_FILES})
-elseif(_UNAME STREQUAL "WIN32")
+if(_UNAME STREQUAL "WIN32")
add_executable(lwpwlp WIN32 ${_SOURCE_FILES})
else()
add_executable(lwpwlp ${_SOURCE_FILES})
@@ -76,11 +69,8 @@ target_link_libraries(lwpwlp PRIVATE ${_LIBS})
if(_UNAME STREQUAL "WIN32")
install(TARGETS lwpwlp
DESTINATION .)
-elseif(_UNAME STREQUAL "LINUX")
- install(TARGETS lwpwlp
- DESTINATION usr/local/bin)
else()
- install(TARGETS lwpwlp
- DESTINATION Layered_WallPaper)
+ install(TARGETS lwpwlp
+ DESTINATION bin)
endif()
diff --git a/src/wlp/main.h b/src/wlp/main.h
index 1d3daef..cdbe86b 100644
--- a/src/wlp/main.h
+++ b/src/wlp/main.h
@@ -13,13 +13,6 @@
#ifdef __WIN32
#include
#include
-#elif __DARWIN
-#include
-#include
-#include
-#include
-#include
-#include
#elif __LINUX
#include
#include
diff --git a/src/wlp/render.c b/src/wlp/render.c
index baec2c4..d0ddc5b 100644
--- a/src/wlp/render.c
+++ b/src/wlp/render.c
@@ -1,8 +1,4 @@
-#ifdef _MSC_VER
-#include
-#else
#include
-#endif
#include "main.h"
diff --git a/src/wlp/window.c b/src/wlp/window.c
index 96b684d..c160103 100644
--- a/src/wlp/window.c
+++ b/src/wlp/window.c
@@ -2,24 +2,27 @@
#ifdef __WIN32
#include
-#endif // __WIN32
+#endif // __WIN32
#ifdef __LINUX
#include
#include
#include
-#endif //__LINUX
+#endif //__LINUX
#ifdef __WIN32
-static HWND iconWorkerw;
-static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam) {
+static HWND iconWorkerw;
+static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam)
+{
char buff[10];
GetClassName(hWnd, buff, 10);
- if (strcmp(buff, "WorkerW") == 0) {
+ if (strcmp(buff, "WorkerW") == 0)
+ {
HWND defView = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL);
- if (defView) {
+ if (defView)
+ {
iconWorkerw = hWnd;
return FALSE;
}
@@ -27,60 +30,15 @@ static BOOL CALLBACK getIconWorkerw(HWND hWnd, LPARAM lParam) {
return TRUE;
}
-#elif __DARWIN
-
-// Helper macros for objc runtime interaction
-#define OBJC_MSG_INT ((id(*)(id, SEL, int))objc_msgSend)
-#define OBJC_MSG_ID ((id(*)(id, SEL, id))objc_msgSend)
-#define OBJC_MSG_PTR ((id(*)(id, SEL, void *))objc_msgSend)
-#define OBJC_MSG_CLS ((id(*)(Class, SEL))objc_msgSend)
-#define OBJC_MSG_CLS_CHR ((id(*)(Class, SEL, char *))objc_msgSend)
-
-void initWindow(Config *cfg) {
- // Get main display size
- const CGDirectDisplayID displayID = CGMainDisplayID();
- const size_t w = CGDisplayPixelsWide(displayID);
- const size_t h = CGDisplayPixelsHigh(displayID);
- const struct CGRect frameRect = {0, 0, w, h};
-
- // Get shared NScfglication instance
- const id ns_cfg = OBJC_MSG_CLS(objc_getClass("NScfglication"),
- sel_getUid("sharedcfglication"));
- OBJC_MSG_INT(ns_cfg, sel_getUid("setActivationPolicy:"),
- 0); // NScfglicationActivationPolicyRegular
-
- // Create NSWindow
- const id window =
- ((id(*)(id, SEL, struct CGRect, int, int, int))objc_msgSend)(
- OBJC_MSG_CLS(objc_getClass("NSWindow"), sel_getUid("alloc")),
- sel_getUid("initWithContentRect:styleMask:backing:defer:"), frameRect,
- 0, // NSWindowStyleMaskBorderless
- 2, // NSBackingStoreBuffered
- false);
-
- // Set window attributes
- OBJC_MSG_ID(window, sel_getUid("setTitle:"),
- OBJC_MSG_CLS_CHR(objc_getClass("NSString"),
- sel_getUid("stringWithUTF8String:"),
- "Parallax wallpaper"));
- OBJC_MSG_PTR(window, sel_getUid("makeKeyAndOrderFront:"), nil);
- OBJC_MSG_INT(window, sel_getUid("setLevel:"), kCGDesktopWindowLevel - 1);
- OBJC_MSG_INT(ns_cfg, sel_getUid("activateIgnoringOthercfgs:"), true);
-
- // Create SDL window from NSWindow
- cfg->window = SDL_CreateWindowFrom((void *)window);
- if (cfg->window == NULL)
- lwpLog(LOG_ERROR, "%s", SDL_GetError());
-}
#endif
-void initWindow(App *app) {
+void initWindow(App *app)
+{
#ifdef __WIN32
- app->window = SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0,
- SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
- if (app->window == NULL)
- lwpLog(LOG_ERROR, "%s", SDL_GetError());
+ app->window =
+ SDL_CreateWindow("Parallax wallpaper", 0, 0, 0, 0, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
+ if (app->window == NULL) lwpLog(LOG_ERROR, "%s", SDL_GetError());
SDL_SysWMinfo sysWmInfo;
SDL_VERSION(&sysWmInfo.version)
@@ -88,65 +46,82 @@ void initWindow(App *app) {
HWND hWindow = sysWmInfo.info.win.window;
HWND progman = FindWindow("Progman", NULL);
- iconWorkerw = progman;
+ iconWorkerw = progman;
SendMessageTimeout(progman, 0x052C, NULL, NULL, SMTO_NORMAL, 1000, NULL);
- if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL))
- EnumWindows(getIconWorkerw, NULL);
+ if (!FindWindowEx(progman, NULL, "SHELLDLL_DefView", NULL)) EnumWindows(getIconWorkerw, NULL);
HWND wallpaperWorkerw = GetWindow(iconWorkerw, GW_HWNDNEXT);
SetParent(hWindow, wallpaperWorkerw);
- SetWindowLongPtr(hWindow, GWL_EXSTYLE,
- WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |
- WS_EX_NOACTIVATE);
+ SetWindowLongPtr(
+ hWindow, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE
+ );
SetWindowLongPtr(hWindow, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE);
- SetWindowPos(hWindow, NULL, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN),
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
-
-#elif __DARWIN
+ SetWindowPos(
+ hWindow,
+ NULL,
+ 0,
+ 0,
+ GetSystemMetrics(SM_CXVIRTUALSCREEN),
+ GetSystemMetrics(SM_CYVIRTUALSCREEN),
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW
+ );
#else
- if (!app->config.drawOnRootWindow) {
+ if (!app->config.drawOnRootWindow)
+ {
Display *display = XOpenDisplay(NULL);
XCloseDisplay(display);
- app->window =
- SDL_CreateWindow("Layered WallPaper", 0, 0, DisplayWidth(display, 0),
- DisplayHeight(display, 0), SDL_WINDOW_OPENGL);
+ app->window = SDL_CreateWindow(
+ "Layered WallPaper",
+ 0,
+ 0,
+ DisplayWidth(display, 0),
+ DisplayHeight(display, 0),
+ SDL_WINDOW_OPENGL
+ );
SDL_SysWMinfo wmInfo;
SDL_GetVersion(&wmInfo.version);
SDL_GetWindowWMInfo(app->window, &wmInfo);
Window xWnd = wmInfo.info.x11.window;
- display = wmInfo.info.x11.display;
+ display = wmInfo.info.x11.display;
- Atom atomType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", 0);
+ Atom atomType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", 0);
Atom atomDesktop = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", 0);
- XChangeProperty(display, xWnd, atomType, XA_ATOM, 32, PropModeReplace,
- (const unsigned char *)&atomDesktop, 1);
+ XChangeProperty(
+ display,
+ xWnd,
+ atomType,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (const unsigned char *)&atomDesktop,
+ 1
+ );
Window rootWindow = RootWindow(display, DefaultScreen(display));
XReparentWindow(display, xWnd, rootWindow, 0, 0);
XSync(display, 0);
- } else {
- Display *display = XOpenDisplay(NULL);
- Window rootWindow = RootWindow(display, DefaultScreen(display));
- app->window = SDL_CreateWindowFrom((void *)rootWindow);
+ }
+ else
+ {
+ Display *display = XOpenDisplay(NULL);
+ Window rootWindow = RootWindow(display, DefaultScreen(display));
+ app->window = SDL_CreateWindowFrom((void *)rootWindow);
XCloseDisplay(display);
}
#endif
- if (app->window == NULL)
- lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
+ if (app->window == NULL) lwpLog(LOG_ERROR, "Failed to initialize window: %s", SDL_GetError());
- app->renderer = SDL_CreateRenderer(
- app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- if (app->renderer == NULL)
- lwpLog(LOG_ERROR, "Failed to initialize renderer: %s", SDL_GetError());
+ app->renderer =
+ SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ if (app->renderer == NULL) lwpLog(LOG_ERROR, "Failed to initialize renderer: %s", SDL_GetError());
}
From 4e34348323811f8665fd819cea820706c036668b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Sat, 9 Mar 2024 16:14:12 +0100
Subject: [PATCH 34/36] Working on Windows
---
src/common/config.c | 2 ++
src/common/paths.c | 7 +++++--
src/core/trayIcon.c | 2 +-
src/core/windowHandlers.c | 16 ++++++++++++++--
src/core/wlp.c | 1 -
src/window_templates/main.glade | 2 +-
6 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/src/common/config.c b/src/common/config.c
index 0ede3a3..292c327 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -104,8 +104,10 @@ void saveAppConfig(AppConfig *ac)
config_init(&cfg);
root = config_root_setting(&cfg);
+#ifdef __LINUX
setting = config_setting_add(root, "draw_on_rootwindow", CONFIG_TYPE_INT);
config_setting_set_int(setting, ac->drawOnRootWindow);
+#endif
setting = config_setting_add(root, "target_fps", CONFIG_TYPE_INT);
config_setting_set_int(setting, ac->targetFps);
setting = config_setting_add(root, "render_quality", CONFIG_TYPE_STRING);
diff --git a/src/common/paths.c b/src/common/paths.c
index e2e79b8..1eeb430 100644
--- a/src/common/paths.c
+++ b/src/common/paths.c
@@ -61,8 +61,11 @@ void getAppDir(char *buff, int type)
sprintf(buff, "%s/%s", prefix, "share/lwp");
}
#elif __WIN32
- GetModuleFileNameA(NULL, buff, PATH_MAX);
- removeLastPathEntry(buff);
+ if (type == APP_DIR_BIN || type == APP_DIR_SHARE)
+ {
+ GetModuleFileNameA(NULL, buff, PATH_MAX);
+ removeLastPathEntry(buff);
+ }
#endif
}
diff --git a/src/core/trayIcon.c b/src/core/trayIcon.c
index b63cdbc..e4d1473 100644
--- a/src/core/trayIcon.c
+++ b/src/core/trayIcon.c
@@ -1,8 +1,8 @@
#ifdef __WIN32
+#include
#include
#include
-#include
#include "main.h"
diff --git a/src/core/windowHandlers.c b/src/core/windowHandlers.c
index b47a504..bc75cfa 100644
--- a/src/core/windowHandlers.c
+++ b/src/core/windowHandlers.c
@@ -16,7 +16,15 @@ G_MODULE_EXPORT void ExitDialog_Yes()
G_MODULE_EXPORT void MainWindow_ManageWallpapersBtnClick()
{
- gtk_widget_set_visible(wallpaperMgrWnd, 1);
+ GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
+ GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(mainWnd),
+ flags,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "This feature will be available in the future");
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ //gtk_widget_set_visible(wallpaperMgrWnd, 1);
}
G_MODULE_EXPORT void MainWindow_MonitorEditBtnClick() { gtk_widget_set_visible(monitorWnd, 1); }
@@ -115,9 +123,13 @@ G_MODULE_EXPORT void SettingsWindowShow()
char targetFpsStr[4];
sprintf(targetFpsStr, "%d", ac.targetFps);
+
+#ifdef __LINUX
char drawOnRootWindowStr[2];
sprintf(drawOnRootWindowStr, "%d", ac.drawOnRootWindow);
-
+#else
+ char *drawOnRootWindowStr = "0";
+#endif
gtk_combo_box_set_active_id(GTK_COMBO_BOX(renderQualityComboBox), ac.renderQuality);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(targetFpsComboBox), targetFpsStr);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(drawOnRootWndComboBox), drawOnRootWindowStr);
diff --git a/src/core/wlp.c b/src/core/wlp.c
index 3ba9668..2542599 100644
--- a/src/core/wlp.c
+++ b/src/core/wlp.c
@@ -45,7 +45,6 @@ void runWlp()
GetModuleFileName(NULL, path, MAX_PATH);
path[_tcslen(path) - 4] = '\0';
_tcscat(path, TEXT("wlp.exe"));
- printf("%s\n", path);
if (CreateProcess(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
hWlpProcess = pi.hProcess;
diff --git a/src/window_templates/main.glade b/src/window_templates/main.glade
index 0c9be83..e3147ed 100644
--- a/src/window_templates/main.glade
+++ b/src/window_templates/main.glade
@@ -576,12 +576,12 @@ Layered WallPaper
500
250
+
True
False
vertical
-
True
From 513147c2bf24361e3d659d85a2e5bd0d160baae4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
<38699473+jszczerbinsky@users.noreply.github.com>
Date: Sat, 9 Mar 2024 16:39:44 +0100
Subject: [PATCH 35/36] Update README.md
---
README.md | 128 ++++++------------------------------------------------
1 file changed, 14 insertions(+), 114 deletions(-)
diff --git a/README.md b/README.md
index 54b2e94..cc31888 100644
--- a/README.md
+++ b/README.md
@@ -32,12 +32,14 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
#### Installation steps
- Download `.tar.gz` package from [releases](https://github.com/jszczerbinsky/lwp/releases/latest)
- - Extract the content to `/`:
+ - Extract the content to `/usr/local`:
```shell
- sudo tar -o -xvf [archive name].tar.gz --directory /
+ sudo tar -o -xvf [archive name].tar.gz --directory /usr/local
```
+ - Note that if You install lwp somewhere else than `/usr/local`, You need to set `LWP_PREFIX` env before running `lwp`.
- Test Layered WallPaper by running `lwp`
- - Setting `reload_rootwindow=1` in config file may be necessary on some distributions for Layered WallPaper to work properly (see [configuration](#configuration))
+ - Run `lwp`, then run it again to open the configuration window. Select wallpaper for each monitor.
+ - If You can't see any wallpaper try setting `Draw on root window` in application settings. This may be necessary on some distributions for Layered WallPaper to work properly (see [configuration](#configuration))
- To make Layered WallPaper run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
#### Build from source instead
@@ -57,48 +59,8 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
cmake --build .
cpack
```
- - Extract `.tar.gz` package
- ```shell
- sudo tar -o -xvf [archive name].tar.gz --directory /
- ```
- - Test Layered WallPaper by running `lwp`
- - Setting `reload_rootwindow=1` in config file may be necessary on some distributions for Layered WallPaper to work properly (see [configuration](#configuration))
- - To make Layered WallPaper run on startup, add `lwp &` command to Your desktop enviroment `.rc` file
-
-
-
-
- macOS
-
- ### Dependencies
- Install the dependencies (homebrew: `brew install sdl2 gtk+3 libconfig`)
+ - After this `.tar.gz` package should appear. Follow the installation steps
- #### Installation steps
- - Download and run the installer from [releases](https://github.com/jszczerbinsky/lwp/releases/latest)
- - Drag and drop Layered_WallPaper into Applications
- - To make Layered WallPaper run on startup, run Toggle_Autorun.command
- - To stop running Layered WallPaper on startup, run it again
-
- #### Build from source instead
- - To build this project, You need to install `cmake` (homebrew: `brew install cmake`)
- - Clone the repository:
- ```zsh
- git clone https://github.com/jszczerbinsky/lwp
- cd lwp
-
- ```
- - Compile and generate installer
- ```zsh
- mkdir build
- cd build
- cmake ../
- cmake --build .
- cpack -G DragNDrop
- ```
- - DMG installer should appear, open it and drag Layered_WallPaper into Applications
- - To make Layered WallPaper run on startup, run Toggle_Autorun.command
- - To stop running Layered WallPaper on startup, run it again
-
@@ -107,29 +69,18 @@ https://user-images.githubusercontent.com/38699473/220888934-09788a6b-873c-469b-
#### Installation steps
- Download and run the installer from [releases](https://github.com/jszczerbinsky/lwp/releases/latest)
- Layered WallPaper should run immediately after the installation
+ - Click the tray icon on the right side of Your taskbar to show the configuration window. Set the wallpapers for each monitor
#### Build from source instead
To compile Layered WallPaper on Windows you need to install [MSYS2](https://www.msys2.org/). After the installation follow the guide for setting up [GTK development enviroment](https://www.gtk.org/docs/installations/windows#using-gtk-from-msys2-packages). From now on continue using MSYS2 MinGW terminal (make sure you're using `MSYS2 MINGW64`/`MSYS2 MINGW32` instead of `MSYS2`).
##### Install the remaining dependencies
-There is a problem with the newest version of SDL2 on MSYS2 repository (see [issue](https://github.com/haskell-game/sdl2/issues/277)), that leads to a compilation error, thus You should install an older version of SDL2 instead.
-```shell
-# For 64bit:
-curl -O https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-SDL2-2.0.14-2-any.pkg.tar.zst
-pacman -U mingw-w64-x86_64-SDL2-2.0.14-2-any.pkg.tar.zst
-
-# For 32bit:
-curl -O https://repo.msys2.org/mingw/i686/mingw-w64-i686-SDL2-2.0.14-2-any.pkg.tar.zst
-pacman -U mingw-w64-i686-SDL2-2.0.14-2-any.pkg.tar.zst
-```
-
-You also have to install cmake
```shell
# For 64bit:
-pacman -S mingw-w64-x86_64-cmake
+pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-gcc mingw-w64-x86_64-gtk3 mingw-w64-x86_64-libconfig
# For 32bit:
-pacman -S mingw-w64-i686-cmake
+pacman -S mingw-w64-i686-cmake mingw-w64-x86_i686-SDL2 mingw-w64-x86_i686-gcc mingw-w64-x86_i686-gtk3 mingw-w64-x86_i686-libconfig
```
##### Clone the repository
@@ -158,61 +109,12 @@ After this the installer should appear in the current directory.
## Configuration
-#### Create a configuration file
-
- Linux
-
- - Copy default config file to `.config/lwp/lwp.cfg`:
- ```shell
- mkdir ~/.config/lwp
- cp /etc/lwp.cfg ~/.config/lwp/lwp.cfg
- ```
-
-
-
- macOS
-
- - Copy default config file to `~/.config/lwp/lwp.cfg`:
- ```zsh
- mkdir -p ~/.config/lwp
- cp /opt/lwp/lwp.cfg ~/.config/lwp/
- ```
-
-
- Windows
-
- - Press ⊞ Win + R
- - Type `%appdata%` and press `Ok`
- - Create new directory and name it `lwp`
- - Copy file `C:\Program Files\lwp\defaultWin.cfg` to directory created in the previous step and rename it to `lwp.cfg`
- - Open `lwp.cfg` in notepad
-
-
+### Open configuration window
+- On Linux when `lwp` is already running in the background, run `lwp` again to show the window.
+- On Windows You can click the icon on the right side of the task bar.
-#### Using config file
-
-- Do not put spaces between `=` and values
-- Do not leave trailing spaces
-- Comments start with `#`
-- Do not put strings in quotation marks
-
-#### Available options:
-
-| Type | Name | Description |
-| ------ | ------------ | ----------- |
-| int | reload_rootwindow | Set this to 1 if You are using a compositor (linux only) |
-| float | smooth | Smooth movement multipler |
-| int | monitors | Monitors count |
-| int | monitor[n]_x | Position of nth monitor in X axis |
-| int | monitor[n]_y | Position of nth monitor in Y axis |
-| int | monitor[n]_w | Width of nth monitor |
-| int | monitor[n]_h | Height of nth monitor |
-| string | monitor[n]_wallpaper | Absolute path to the wallpaper directory |
-| int | monitor[n]_wallpaper_x | Position of the wallpaper relative to the monitor |
-| int | monitor[n]_wallpaper_y | Position of the wallpaper relative to the monitor |
-| int | monitor[n]_wallpaper_w | Wallpaper resolution |
-| int | monitor[n]_wallpaper_h | Wallpaper resolution |
-| int | target_fps | How many times per second should the wallpaper render (imprecise, hence "target") |
+### Installing wallpapers
+- To install wallpaper, copy the directory to `%LOCALAPPDATA%\lwp\wallpapers\`
## Creating Wallpapers
@@ -244,8 +146,6 @@ C:
| int | count | Wallpaper layers count |
| float | movement_x | Mouse sensitivity in X axis |
| float | movement_y | Mouse sensitivity in Y axis |
-| float | movement[n]_x | Mouse sensitivity in X axis for nth layer (optional)|
-| float | movement[n]_y | Mouse sensitivity in Y axis for nth layer (optional)|
| int | repeat_x | Repeat the wallpaper in X axis |
| int | repeat_y | Repeat the wallpaper in Y axis |
From 389bceee7014e967faadfce3c47ad1a526c6904e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Szczerbi=C5=84ski?=
Date: Sat, 9 Mar 2024 16:42:21 +0100
Subject: [PATCH 36/36] Removed unnecessary files
---
default.cfg | 2 --
defaultMac.cfg | 36 ----------------------
defaultWin.cfg | 36 ----------------------
dmgBg.png | Bin 172756 -> 0 bytes
install.bat | 72 -------------------------------------------
lwp.template.plist | 22 -------------
setupDmg.applescript | 21 -------------
setupPlist.command | 16 ----------
uninstall.bat | 26 ----------------
9 files changed, 231 deletions(-)
delete mode 100644 default.cfg
delete mode 100644 defaultMac.cfg
delete mode 100644 defaultWin.cfg
delete mode 100644 dmgBg.png
delete mode 100644 install.bat
delete mode 100644 lwp.template.plist
delete mode 100755 setupDmg.applescript
delete mode 100755 setupPlist.command
delete mode 100644 uninstall.bat
diff --git a/default.cfg b/default.cfg
deleted file mode 100644
index ab24da3..0000000
--- a/default.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-draw_on_rootwindow= 0;
-target_fps = 60;
diff --git a/defaultMac.cfg b/defaultMac.cfg
deleted file mode 100644
index 88372be..0000000
--- a/defaultMac.cfg
+++ /dev/null
@@ -1,36 +0,0 @@
-# ██╗ ██╗ ██╗██████╗
-# ██║ ██║ ██║██╔══██╗
-# ██║ ██║ █╗ ██║██████╔╝
-# ██║ ██║███╗██║██╔═══╝
-# ███████╗╚███╔███╔╝██║
-# ╚══════╝ ╚══╝╚══╝ ╚═╝
-
-# Smooth movement
-# Increasing this value will make the wallpaper layers move faster
-smooth=8.0
-
-# Monitors count
-monitors=1
-
-# Monitor position
-monitor1_x=0
-monitor1_y=0
-
-# Monitor resolution
-monitor1_w=1920
-monitor1_h=1080
-
-# Absolute path to the wallpaper directory
-# Leave the value as empty to use the default wallpaper
-monitor1_wallpaper=/Applications/Layered_WallPaper/wallpapers/default-fullhd
-
-# Wallpaper size and position relative to Your monitor
-# Wallpaper resolution ratio should be the same as in original image
-monitor1_wallpaper_x=0
-monitor1_wallpaper_y=0
-monitor1_wallpaper_w=1920
-monitor1_wallpaper_h=1080
-
-# How many times per second should the wallpaper render
-# (imprecise, but accurate enough)
-target_fps=60
diff --git a/defaultWin.cfg b/defaultWin.cfg
deleted file mode 100644
index 761e0fc..0000000
--- a/defaultWin.cfg
+++ /dev/null
@@ -1,36 +0,0 @@
-# ██╗ ██╗ ██╗██████╗
-# ██║ ██║ ██║██╔══██╗
-# ██║ ██║ █╗ ██║██████╔╝
-# ██║ ██║███╗██║██╔═══╝
-# ███████╗╚███╔███╔╝██║
-# ╚══════╝ ╚══╝╚══╝ ╚═╝
-
-# Smooth movement
-# Increasing this value will make the wallpaper layers move faster
-smooth=8.0
-
-# Monitors count
-monitors=1
-
-# Monitor position
-monitor1_x=0
-monitor1_y=0
-
-# Monitor resolution
-monitor1_w=1920
-monitor1_h=1080
-
-# Absolute path to the wallpaper directory
-# Leave the value as empty to use the default wallpaper
-monitor1_wallpaper=
-
-# Wallpaper size and position relative to Your monitor
-# Wallpaper resolution ratio should be the same as in original image
-monitor1_wallpaper_x=0
-monitor1_wallpaper_y=0
-monitor1_wallpaper_w=1920
-monitor1_wallpaper_h=1080
-
-# How many times per second should the wallpaper render
-# (imprecise, but accurate enough)
-target_fps=60
diff --git a/dmgBg.png b/dmgBg.png
deleted file mode 100644
index 99bf59214fc3a82c8ecc28e7799d2dd6e984491c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 172756
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 !e
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