Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mpvpaper for openSUSE:Factory checked in at 2023-11-03 22:20:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mpvpaper (Old) and /work/SRC/openSUSE:Factory/.mpvpaper.new.17445 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mpvpaper" Fri Nov 3 22:20:56 2023 rev:9 rq:1123176 version:1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/mpvpaper/mpvpaper.changes 2022-09-26 18:48:25.704079714 +0200 +++ /work/SRC/openSUSE:Factory/.mpvpaper.new.17445/mpvpaper.changes 2023-11-03 22:21:43.983554722 +0100 @@ -1,0 +2,10 @@ +Fri Nov 3 09:56:27 UTC 2023 - Michael Vetter <mvet...@suse.com> + +- Update to 1.4: + * New "--help-output/-d" option to show outputs without "mpvpaper -v a a" + * Improve verbose and error messages + * Move and fix up EGL and mpv inits + * Small cleanups for "pausing" and "stopping" behavior + * Fix int overflow for getopt_long() on ARM + +------------------------------------------------------------------- Old: ---- 1.3.tar.gz New: ---- 1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mpvpaper.spec ++++++ --- /var/tmp/diff_new_pack.fCAWce/_old 2023-11-03 22:21:44.647579148 +0100 +++ /var/tmp/diff_new_pack.fCAWce/_new 2023-11-03 22:21:44.647579148 +0100 @@ -1,7 +1,7 @@ # # spec file for package mpvpaper # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: mpvpaper -Version: 1.3 +Version: 1.4 Release: 0 Summary: A video wallpaper program for wlroots based wayland compositors License: GPL-3.0-or-later ++++++ 1.3.tar.gz -> 1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpvpaper-1.3/README.md new/mpvpaper-1.4/README.md --- old/mpvpaper-1.3/README.md 2022-09-23 21:39:12.000000000 +0200 +++ new/mpvpaper-1.4/README.md 2023-11-02 19:40:09.000000000 +0100 @@ -47,11 +47,7 @@ echo 'cycle pause' | socat - /tmp/mpv-socket ``` For more mpv commands read: https://mpv.io/manual/master/#command-interface -## Notes -To see display outputs names, check the "not selected" error messages of: -``` -mpvpaper -v a a -``` + For more info on mpvpaper, please refer the the [man page](/mpvpaper.man). ## Acknowledgments - glpaper and swaybg for the initial boilerplate code, check em out here: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpvpaper-1.3/mpvpaper.man new/mpvpaper-1.4/mpvpaper.man --- old/mpvpaper-1.3/mpvpaper.man 2022-09-23 21:39:12.000000000 +0200 +++ new/mpvpaper-1.4/mpvpaper.man 2023-11-02 19:40:09.000000000 +0100 @@ -14,8 +14,11 @@ \fB\-h\fR, \fB\-\-help\fR Displays usage options .TP +\fB\-d\fR, \fB\-\-help-output\fR +Displays all available outputs and quits +.TP \fB\-v\fR, \fB\-\-verbose\fR -Be more verbose +Be more verbose (-vv for higher verbosity) .TP \fB\-f\fR, \fB\-\-fork\fR Forks mpvpaper so you can close the terminal @@ -54,11 +57,6 @@ mpvpaper '*' /path/to/video .RE -To see display outputs names, check the "not selected" error messages of: -.RS -mpvpaper -v a a -.RE - Forward mpv options by passing "--mpv-options" or "-o" like so: .RS mpvpaper -o "no-audio --loop-playlist shuffle" HDMI-A-1 www.url/to/playlist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpvpaper-1.3/src/holder.c new/mpvpaper-1.4/src/holder.c --- old/mpvpaper-1.3/src/holder.c 2022-09-23 21:39:12.000000000 +0200 +++ new/mpvpaper-1.4/src/holder.c 2023-11-02 19:40:09.000000000 +0100 @@ -39,11 +39,10 @@ static struct { char **argv_copy; char **stoplist; - bool auto_stop; int start_time; -} halt_info = {NULL, NULL, 0, 0}; +} halt_info = {NULL, NULL, false, 0}; static void nop() {} @@ -112,19 +111,20 @@ wl_buffer_destroy(dummy_buffer); } -static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t time) { +static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t frame_time) { + (void)frame_time; wl_callback_destroy(callback); if (halt_info.stoplist) { - check_stoplist(); - // If checking stoplist took longer than a second don't revive - if (time - halt_info.start_time < 1000) + check_stoplist(); + // If checking stoplist and frame callback took longer than a second don't revive + if (frame_time - halt_info.start_time < 1000) revive_mpvpaper(); - } - else + } else { revive_mpvpaper(); + } - halt_info.start_time = time; + halt_info.start_time = frame_time; create_surface_frame(data); } @@ -133,24 +133,22 @@ }; static void destroy_display_output(struct display_output *output) { - if (!output) { + if (!output) return; - } wl_list_remove(&output->link); - if (output->layer_surface != NULL) { + if (output->layer_surface != NULL) zwlr_layer_surface_v1_destroy(output->layer_surface); - } - if (output->surface != NULL) { + if (output->surface != NULL) wl_surface_destroy(output->surface); - } wl_output_destroy(output->wl_output); free(output->name); free(output); } -static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, - uint32_t serial, uint32_t width, uint32_t height) { +static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, + uint32_t width, uint32_t height) { + struct display_output *output = data; output->width = width; output->height = height; @@ -208,14 +206,11 @@ struct display_output *output = data; - bool name_ok = (strcmp(output->name, output->state->monitor) == 0) || - (strcmp(output->state->monitor, "*") == 0); - if (name_ok && !output->layer_surface) { + bool name_ok = (strcmp(output->name, output->state->monitor) == 0) || (strcmp(output->state->monitor, "*") == 0); + if (name_ok && !output->layer_surface) create_layer_surface(output); - } - if (!name_ok) { + if (!name_ok) destroy_display_output(output); - } } static const struct wl_output_listener output_listener = { @@ -233,11 +228,9 @@ struct wl_state *state = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { state->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 4); - } - else if (strcmp(interface, wl_shm_interface.name) == 0) { + } else if (strcmp(interface, wl_shm_interface.name) == 0) { state->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); - } - else if (strcmp(interface, wl_output_interface.name) == 0) { + } else if (strcmp(interface, wl_output_interface.name) == 0) { struct display_output *output = calloc(1, sizeof(struct display_output)); output->state = state; output->wl_name = name; @@ -246,7 +239,7 @@ wl_list_insert(&state->outputs, &output->link); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { - state->layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); + state->layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface,1); } } @@ -268,6 +261,14 @@ .global_remove = handle_global_remove, }; +static void copy_argv(int argc, char* argv[]) { + halt_info.argv_copy = calloc(argc+1, sizeof(char*)); + + for (int i = 0; i < argc; i++) { + halt_info.argv_copy[i] = strdup(argv[i]); + } +} + static void set_stop_list() { char *stop_path = calloc(strlen(getenv("HOME"))+1 + strlen("/.config/mpvpaper/stoplist")+1, sizeof(char)); @@ -345,21 +346,11 @@ parse_command_line(argc, argv, &state); set_stop_list(); - - // Copy argv - int argv_alloc_size = 0; - for (int i=0; argv[i] != NULL; i++) { - argv_alloc_size += strlen(argv[i])+1; - } - halt_info.argv_copy = calloc(argv_alloc_size+1, sizeof(char)); - for (int i=0; i < argc; i++) { - halt_info.argv_copy[i] = strdup(argv[i]); - } + copy_argv(argc, argv); state.display = wl_display_connect(NULL); - if (!state.display) { + if (!state.display) return EXIT_FAILURE; - } struct wl_registry *registry = wl_display_get_registry(state.display); wl_registry_add_listener(registry, ®istry_listener, &state); @@ -370,9 +361,8 @@ // Check outputs wl_display_roundtrip(state.display); - if (wl_list_empty(&state.outputs)) { + if (wl_list_empty(&state.outputs)) return EXIT_FAILURE; - } while (wl_display_dispatch(state.display) != -1) { // NOP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpvpaper-1.3/src/main.c new/mpvpaper-1.4/src/main.c --- old/mpvpaper-1.3/src/main.c 2022-09-23 21:39:12.000000000 +0200 +++ new/mpvpaper-1.4/src/main.c 2023-11-02 19:40:09.000000000 +0100 @@ -69,6 +69,7 @@ char **pauselist; char **stoplist; + int argc; char **argv_copy; char *save_info; @@ -79,12 +80,13 @@ bool frame_ready; bool stop_render_loop; -} halt_info = {NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}; +} halt_info = {NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, 0}; static pthread_t threads[5] = {0}; static uint SLIDESHOW_TIME = 0; -static bool VERBOSE = 0; +static bool SHOW_OUTPUTS = false; +static int VERBOSE = 0; static void nop() {} @@ -147,16 +149,15 @@ {MPV_RENDER_PARAM_INVALID, NULL}, }; - if (!eglMakeCurrent(egl_display, output->egl_surface, output->egl_surface, egl_context)) { + if (!eglMakeCurrent(egl_display, output->egl_surface, output->egl_surface, egl_context)) cflp_error("Failed to make output surface current 0x%X", eglGetError()); - } + glViewport(0, 0, output->width * output->scale, output->height * output->scale); // Render frame - int err = mpv_render_context_render(mpv_glcontext, render_params); - if (err < 0) { - cflp_error("Failed to render frame with mpv, %s", mpv_error_string(err)); - } + int mpv_err = mpv_render_context_render(mpv_glcontext, render_params); + if (mpv_err < 0) + cflp_error("Failed to render frame with mpv, %s", mpv_error_string(mpv_err)); // Callback new frame output->frame_callback = wl_surface_frame(output->surface); @@ -171,28 +172,20 @@ static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t frame_time) { (void)frame_time; struct display_output *output = data; - output->frame_callback = NULL; wl_callback_destroy(callback); + // Display is ready for new frame + output->frame_callback = NULL; + // Reset deadman switch timer halt_info.frame_ready = 1; - // Sleep more while paused - if (halt_info.is_paused) { - int start_time = time(NULL); - while (halt_info.is_paused) { - if (time(NULL) - start_time >= 1) - break; - if (halt_info.stop_render_loop) { - halt_info.stop_render_loop = 0; - } - usleep(1000); - } - } - // Render next frame - if (output->redraw_needed) + if (output->redraw_needed) { + if (VERBOSE == 2) + cflp_info("%s is ready for MPV to render the next frame", output->name); render(output); + } } const static struct wl_callback_listener wl_surface_frame_listener = { @@ -206,21 +199,17 @@ const char *playlist_pos = mpv_get_property_string(mpv, "playlist-pos"); char save_info[30]; - sprintf(save_info, "%s %s", time_pos, playlist_pos); + snprintf(save_info, sizeof(save_info), "%s %s", time_pos, playlist_pos); - int argv_alloc_size = strlen("-Z")+1 + strlen(save_info)+1; - for (uint i=0; halt_info.argv_copy[i] != NULL; i++) { - argv_alloc_size += strlen(halt_info.argv_copy[i])+1; - } - char **argv = calloc(argv_alloc_size+1, sizeof(char)); + char **new_argv = calloc(halt_info.argc+3, sizeof(char*)); // Plus 3 for adding in -Z - uint i = 0; - for (i=0; halt_info.argv_copy[i] != NULL; i++) { - argv[i] = strdup(halt_info.argv_copy[i]); + int i; + for (i = 0; i < halt_info.argc; i++) { + new_argv[i] = strdup(halt_info.argv_copy[i]); } - argv[i] = "-Z"; - argv[i+1] = save_info; - argv[i+2] = NULL; + new_argv[i] = strdup("-Z"); + new_argv[i+1] = strdup(save_info); + new_argv[i+2] = NULL; // Get the "real" cwd char exe_dir[1024]; @@ -235,7 +224,7 @@ exit_cleanup(); // Start holder script - execv(strcat(exe_dir, "mpvpaper-holder"), argv); + execv(strcat(exe_dir, "mpvpaper-holder"), new_argv); cflp_error("Failed to stop mpvpaper"); exit(EXIT_FAILURE); @@ -263,36 +252,31 @@ strcat(pid_name, " > /dev/null"); // Stop if program is open - if (!system(pid_name)) { + if (!system(pid_name)) return list[i]; - } } return NULL; } static void *monitor_pauselist() { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - bool is_paused = 0; + bool list_paused = 0; while (halt_info.pauselist) { - if (!halt_info.is_paused) { - char *app; - while ((app = check_watch_list(halt_info.pauselist))) { - if (app && !is_paused) { - if (VERBOSE) - cflp_info("Pausing for %s", app); - mpv_command_async(mpv, 0, (const char*[]) {"set", "pause", "yes", NULL}); - is_paused = 1; - halt_info.is_paused += 1; - } - pthread_sleep(1); - } - if (is_paused) { - is_paused = 0; - if (halt_info.is_paused) - halt_info.is_paused -= 1; - } + + char *app = check_watch_list(halt_info.pauselist); + if (app && !list_paused && !halt_info.is_paused) { + if (VERBOSE) + cflp_info("Pausing for %s", app); + mpv_command_async(mpv, 0, (const char*[]) {"set", "pause", "yes", NULL}); + list_paused = 1; + halt_info.is_paused += 1; + } else if (!app && list_paused) { + list_paused = 0; + if (halt_info.is_paused) + halt_info.is_paused -= 1; } + pthread_sleep(1); } pthread_exit(NULL); @@ -302,12 +286,14 @@ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); while (halt_info.stoplist) { + char *app = check_watch_list(halt_info.stoplist); if (app) { if (VERBOSE) cflp_info("Stopping for %s", app); stop_mpvpaper(); } + pthread_sleep(1); } pthread_exit(NULL); @@ -317,29 +303,22 @@ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); while (halt_info.auto_pause) { - if (!halt_info.is_paused) { - time_t start_time = time(NULL); - bool is_paused = 0; - - // Set deadman switch timer - halt_info.frame_ready = 0; - while (!halt_info.frame_ready) { - if ((time(NULL) - start_time) >= 2 && !is_paused) { - if (VERBOSE) - cflp_info("Pausing because mpvpaper is hidden"); - mpv_command_async(mpv, 0, (const char*[]) {"set", "pause", "yes", NULL}); - is_paused = 1; - halt_info.is_paused += 1; - } + + // Set deadman switch timer + halt_info.frame_ready = 0; + pthread_sleep(2); + if (!halt_info.frame_ready && !halt_info.is_paused) { + if (VERBOSE) + cflp_info("Pausing because mpvpaper is hidden"); + mpv_command_async(mpv, 0, (const char*[]) {"set", "pause", "yes", NULL}); + halt_info.is_paused += 1; + + while(!halt_info.frame_ready) { pthread_usleep(10000); } - if (is_paused) { - is_paused = 0; - if (halt_info.is_paused) - halt_info.is_paused -= 1; - } + if (halt_info.is_paused) + halt_info.is_paused -= 1; } - pthread_sleep(1); } pthread_exit(NULL); } @@ -348,20 +327,15 @@ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); while (halt_info.auto_stop) { - time_t start_time = time(NULL); // Set deadman switch timer halt_info.frame_ready = 0; - while (!halt_info.frame_ready) { - if ((time(NULL) - start_time) >= 2) { - if (VERBOSE) + pthread_sleep(2); + if (!halt_info.frame_ready) { + if (VERBOSE) cflp_info("Stopping because mpvpaper is hidden"); - stop_mpvpaper(); - break; - } - pthread_usleep(10000); + stop_mpvpaper(); } - pthread_sleep(1); } pthread_exit(NULL); } @@ -399,9 +373,8 @@ } } - if (!halt_info.is_paused && mpv_paused) { + if (!halt_info.is_paused && mpv_paused) mpv_command_async(mpv, 0, (const char*[]) {"set", "pause", "no", NULL}); - } pthread_usleep(10000); } @@ -496,11 +469,13 @@ static void render_update_callback(void *callback_ctx) { (void)callback_ctx; uint8_t tmp = 0; + if (write(wakeup_pipe[1], &tmp, 1) == -1) exit_mpvpaper(EXIT_FAILURE); } -static void init_mpv(struct display_output *output) { +static void init_mpv(const struct wl_state *state) { + int mpv_err; mpv = mpv_create(); if (!mpv) { @@ -508,11 +483,11 @@ exit_mpvpaper(EXIT_FAILURE); } - set_init_mpv_options(output->state); + set_init_mpv_options(state); - int err = mpv_initialize(mpv); - if (err < 0) { - cflp_error("Failed to init mpv, %s", mpv_error_string(err)); + mpv_err = mpv_initialize(mpv); + if (mpv_err < 0) { + cflp_error("Failed to init mpv, %s", mpv_error_string(mpv_err)); exit_mpvpaper(EXIT_FAILURE); } @@ -525,23 +500,29 @@ // Have mpv render onto egl context mpv_render_param params[] = { - {MPV_RENDER_PARAM_WL_DISPLAY, output->state->display}, + {MPV_RENDER_PARAM_WL_DISPLAY, state->display}, {MPV_RENDER_PARAM_API_TYPE, MPV_RENDER_API_TYPE_OPENGL}, {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &(mpv_opengl_init_params){ .get_proc_address = get_proc_address_mpv, }}, {MPV_RENDER_PARAM_INVALID, NULL}, }; - if (mpv_render_context_create(&mpv_glcontext, mpv, params) < 0) - cflp_error("Failed to initialize mpv GL context"); + mpv_err = mpv_render_context_create(&mpv_glcontext, mpv, params); + if (mpv_err < 0) { + cflp_error("Failed to initialize mpv GL context, %s", mpv_error_string(mpv_err)); + exit_mpvpaper(EXIT_FAILURE); + } // Restore video position after auto stop event char *default_start = NULL; if (halt_info.save_info) { + char time_pos[10]; char playlist_pos[10]; sscanf(halt_info.save_info, "%s %s", time_pos, playlist_pos); + if (VERBOSE) + cflp_info("Restoring previous time: %s and playlist position: %s", time_pos, playlist_pos); // Save default start pos default_start = mpv_get_property_string(mpv, "start"); // Restore video position @@ -571,7 +552,14 @@ static void init_egl(struct wl_state *state) { egl_display = eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, state->display, NULL); - eglInitialize(egl_display, NULL, NULL); + if (egl_display == EGL_NO_DISPLAY) { + cflp_error("Failed to get EGL display"); + exit_mpvpaper(EXIT_FAILURE); + } + if (!eglInitialize(egl_display, NULL, NULL)) { + cflp_error("Failed to initialize EGL 0x%X", eglGetError()); + exit_mpvpaper(EXIT_FAILURE); + } eglBindAPI(EGL_OPENGL_API); const EGLint win_attrib[] = { @@ -583,8 +571,11 @@ EGL_NONE }; - EGLint config_len; - eglChooseConfig(egl_display, win_attrib, &egl_config, 1, &config_len); + EGLint num_config; + if (!eglChooseConfig(egl_display, win_attrib, &egl_config, 1, &num_config)) { + cflp_error("Failed to set EGL frame buffer config 0x%X", eglGetError()); + exit_mpvpaper(EXIT_FAILURE); + } // Check for OpenGL compatibility for creating egl context static const struct { int major, minor; } gl_versions[] = { @@ -596,50 +587,44 @@ for (uint i = 0; gl_versions[i].major > 0; i++) { const EGLint ctx_attrib[] = { EGL_CONTEXT_MAJOR_VERSION, gl_versions[i].major, - EGL_CONTEXT_MINOR_VERSION, gl_versions[i].major, + EGL_CONTEXT_MINOR_VERSION, gl_versions[i].minor, EGL_NONE }; egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, ctx_attrib); if (egl_context) { - if (VERBOSE) { + if (VERBOSE) cflp_info("OpenGL %i.%i EGL context created", gl_versions[i].major, gl_versions[i].minor); - } break; } } if (!egl_context) { - cflp_error("Failed to create EGL context"); + cflp_error("Failed to create EGL context 0x%X", eglGetError()); exit_mpvpaper(EXIT_FAILURE); } if (!eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context)) { - cflp_error("Failed to make context current"); + cflp_error("Failed to make context current 0x%X", eglGetError()); exit_mpvpaper(EXIT_FAILURE); } if (!gladLoadGLLoader((GLADloadproc)eglGetProcAddress)) { - cflp_error("Failed to load OpenGL"); + cflp_error("Failed to load OpenGL 0x%X", eglGetError()); exit_mpvpaper(EXIT_FAILURE); } } static void destroy_display_output(struct display_output *output) { - if (!output) { + if (!output) return; - } wl_list_remove(&output->link); - if (output->layer_surface != NULL) { + if (output->layer_surface != NULL) zwlr_layer_surface_v1_destroy(output->layer_surface); - } - if (output->surface != NULL) { + if (output->surface != NULL) wl_surface_destroy(output->surface); - } - if (output->egl_surface) { + if (output->egl_surface) eglDestroySurface(egl_display, output->egl_surface); - } - if (output->egl_window) { + if (output->egl_window) wl_egl_window_destroy(output->egl_window); - } wl_output_destroy(output->wl_output); free(output->name); @@ -647,29 +632,26 @@ free(output); } -static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, +static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { - + struct display_output *output = data; output->width = width; output->height = height; zwlr_layer_surface_v1_ack_configure(surface, serial); wl_surface_set_buffer_scale(output->surface, output->scale); - // Setup render loop - struct wl_state *state = output->state; - if (!egl_display) { - init_egl(state); - } - if (!mpv) { - init_mpv(output); - init_threads(); - } - if (!output->egl_window) { output->egl_window = wl_egl_window_create(output->surface, output->width * output->scale, output->height * output->scale); output->egl_surface = eglCreatePlatformWindowSurface(egl_display, egl_config, output->egl_window, NULL); - eglMakeCurrent(egl_display, output->egl_surface, output->egl_surface, egl_context); + if (!output->egl_surface) { + cflp_error("Failed to create EGL surface for %s 0x%X", output->name, eglGetError()); + destroy_display_output(output); + return; + } + + if (!eglMakeCurrent(egl_display, output->egl_surface, output->egl_surface, egl_context)) + cflp_error("Failed to make output surface current 0x%X", eglGetError()); eglSwapInterval(egl_display, 0); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -736,8 +718,8 @@ create_layer_surface(output); } if (!name_ok) { - if (VERBOSE) - cflp_warning("Output %s (%s) not selected", output->name, output->identifier); + if (SHOW_OUTPUTS) + cflp_info("Output %s (%s) found", output->name, output->identifier); destroy_display_output(output); } } @@ -838,17 +820,15 @@ return NULL; } -static void copy_argv(int argc, char **argv) { - int argv_alloc_size = 0; - for (int i=0; argv[i] != NULL; i++) { - argv_alloc_size += strlen(argv[i])+1; - } - halt_info.argv_copy = calloc(argv_alloc_size, sizeof(char)); +static void copy_argv(int argc, char* argv[]) { + halt_info.argc = argc; + halt_info.argv_copy = calloc(argc+1, sizeof(char*)); int j = 0; for (int i=0; i < argc; i++) { if (strcmp(argv[i], "-Z") == 0) { // Remove hidden opt i++; // Skip optind + halt_info.argc -= 2; } else { halt_info.argv_copy[j] = strdup(argv[i]); j++; @@ -870,12 +850,18 @@ strcat(stop_path, "/.config/mpvpaper/stoplist"); halt_info.stoplist = get_watch_list(stop_path); free(stop_path); + + if (VERBOSE && halt_info.pauselist) + cflp_info("pauselist found and will be monitored"); + if (VERBOSE && halt_info.stoplist) + cflp_info("stoplist found and will be monitored"); } static void parse_command_line(int argc, char **argv, struct wl_state *state) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, + {"help-output", no_argument, NULL, 'd'}, {"verbose", no_argument, NULL, 'v'}, {"fork", no_argument, NULL, 'f'}, {"auto-pause", no_argument, NULL, 'p'}, @@ -892,7 +878,8 @@ "\n" "Options:\n" "--help -h Displays this help message\n" - "--verbose -v Be more verbose\n" + "--help-output -d Displays all available outputs and quits\n" + "--verbose -v Be more verbose (-vv for higher verbosity)\n" "--fork -f Forks mpvpaper so you can close the terminal\n" "--auto-pause -p Automagically* pause mpv when the wallpaper is hidden\n" " This saves CPU usage, more or less, seamlessly\n" @@ -907,20 +894,24 @@ char *layer_name; - char opt; - while ((opt = getopt_long(argc, argv, "hvfpsn:l:o:Z:", long_options, NULL)) != -1) { + int opt; + while ((opt = getopt_long(argc, argv, "hdvfpsn:l:o:Z:", long_options, NULL)) != -1) { switch (opt) { case 'h': fprintf(stdout, "%s", usage); exit(EXIT_SUCCESS); + case 'd': + SHOW_OUTPUTS = true; + state->monitor = ""; + return; case 'v': - VERBOSE = 1; + VERBOSE += 1; break; case 'f': - if (fork() > 0) { + if (fork() > 0) exit(EXIT_SUCCESS); - } + fclose(stdout); fclose(stderr); fclose(stdin); @@ -974,6 +965,9 @@ } } + if (VERBOSE) + cflp_info("Verbose Level %i enabled", VERBOSE); + // Need at least a display and video if (optind + 1 >= argc) { cflp_error("Not enough args passed"); @@ -989,15 +983,15 @@ // Check for other wallpaper process running const char *other_wallpapers[] = {"swaybg", "glpaper", "hyprpaper", "wpaperd"}; char wallpaper_sbuffer[50] = {0}; + for (int i=0; i < sizeof(other_wallpapers) / sizeof(other_wallpapers[0]); i++) { strcpy(wallpaper_sbuffer, "pidof "); strcat(wallpaper_sbuffer, other_wallpapers[i]); strcat(wallpaper_sbuffer, " > /dev/null"); - if (!system(wallpaper_sbuffer)) { + if (!system(wallpaper_sbuffer)) cflp_warning("%s is running. This may block mpvpaper from being seen.", other_wallpapers[i]); - } } } @@ -1032,7 +1026,22 @@ "If your compositor is running, check or set the WAYLAND_DISPLAY environment variable."); return EXIT_FAILURE; } + if (VERBOSE) + cflp_success("Connected to Wayland compositor"); + + // Don't start egl and mpv if just displaying outputs + if (!SHOW_OUTPUTS) { + // Init render before outputs + init_egl(&state); + if (VERBOSE) + cflp_success("EGL initialized"); + init_mpv(&state); + init_threads(); + if (VERBOSE) + cflp_success("MPV initialized"); + } + // Setup wayland surfaces struct wl_registry *registry = wl_display_get_registry(state.display); wl_registry_add_listener(registry, ®istry_listener, &state); wl_display_roundtrip(state.display); @@ -1043,6 +1052,8 @@ // Check outputs wl_display_roundtrip(state.display); + if (SHOW_OUTPUTS) + exit(EXIT_SUCCESS); if (wl_list_empty(&state.outputs)) { cflp_error(":/ sorry about this but we can't seem to find any output."); return EXIT_FAILURE; @@ -1091,11 +1102,15 @@ wl_list_for_each(output, &state.outputs, link) { // Redraw immediately if not waiting for frame callback if (output->frame_callback == NULL) { - if (output->egl_window && output->egl_surface) - render(output); - } - else + // Avoid crash when output is destroyed + if (output->egl_window && output->egl_surface) { + if (VERBOSE == 2) + cflp_info("MPV is ready to render the next frame for %s", output->name); + render(output); + } + } else { output->redraw_needed = true; + } } } }