From: Eli Zaretskii Date: Thu, 15 Sep 2022 11:51:31 +0000 (+0300) Subject: Implement support for 'wallpaper-set' on MS-Windows X-Git-Tag: emacs-29.0.90~1856^2~486 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=09e93c4dafc6ffa3e556429757348adfa49a5a83;p=emacs.git Implement support for 'wallpaper-set' on MS-Windows * src/w32fns.c (Fw32_set_wallpaper): New primitive. (syms_of_w32fns): Defsubr it. (globals_of_w32fns): Attempt to load SystemParametersInfoW from its DLL at run time. * lisp/image/wallpaper.el (wallpaper-set): Support MS-Windows by calling 'w32-set-wallpaper'. * etc/NEWS: Update and simplify wording of the 'wallpaper-set' entry. --- diff --git a/etc/NEWS b/etc/NEWS index c88af4e90cf..cc68cd82b86 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2463,17 +2463,13 @@ to optionally rotate images which have the :rotation property. --- ** New package 'wallpaper'. -This package provides the command `wallpaper-set', which sets the -desktop background. - -On GNU/Linux and other Unix-like systems, it uses an external command -(such as "swaybg", "gm", "display" or "xloadimage"). A suitable -command should be detected automatically in most cases, but can also -be customized manually with the new user options 'wallpaper-command' -and 'wallpaper-command-args' if needed. - -On Haiku, it uses the new function `haiku-set-wallpaper', which does -not rely on any external command. +This package provides the command 'wallpaper-set', which sets the +desktop background image. Depending on the system and the desktop, +this may require an external program (such as 'swaybg', 'gm', +'display' or 'xloadimage'). If so, a suitable command should be +detected automatically in most cases, and can also be customized +manually if needed using the new user options 'wallpaper-command' and +'wallpaper-command-args'. +++ ** New package 'oclosure'. diff --git a/lisp/image/wallpaper.el b/lisp/image/wallpaper.el index 2ebe5be0330..ef2ad31eba7 100644 --- a/lisp/image/wallpaper.el +++ b/lisp/image/wallpaper.el @@ -240,7 +240,9 @@ On Haiku, no external command is needed, so the value of (error "No such file: %s" file)) (unless (file-readable-p file) (error "File is not readable: %s" file)) - (cond ((featurep 'haiku) + (cond ((eq system-type 'windows-nt) + (w32-set-wallpaper file)) + ((featurep 'haiku) (haiku-set-wallpaper file)) (t (let* ((fmt-spec `((?f . ,(expand-file-name file)) diff --git a/src/w32fns.c b/src/w32fns.c index 745458d0a03..d9070675a28 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -10447,6 +10447,66 @@ w32_get_resource (const char *key, const char *name, LPDWORD lpdwtype) return (NULL); } +#ifdef WINDOWSNT + +/*********************************************************************** + Wallpaper + ***********************************************************************/ + +typedef BOOL (WINAPI * SystemParametersInfoW_Proc) (UINT,UINT,PVOID,UINT); +SystemParametersInfoW_Proc system_parameters_info_w_fn = NULL; + +DEFUN ("w32-set-wallpaper", Fw32_set_wallpaper, Sw32_set_wallpaper, 1, 1, 0, + doc: /* Set the desktop wallpaper image to IMAGE-FILE. */) + (Lisp_Object image_file) +{ + Lisp_Object encoded = ENCODE_FILE (Fexpand_file_name (image_file, Qnil)); + char *fname = SSDATA (encoded); + BOOL result = false; + DWORD err = 0; + + /* UNICOWS.DLL seems to have SystemParametersInfoW, but it doesn't + seem to be worth the hassle to support that on Windows 9X for the + benefit of this minor feature. Let them use on Windows 9X only + image file names that can be encoded by the system codepage. */ + if (w32_unicode_filenames && system_parameters_info_w_fn) + { + wchar_t fname_w[MAX_PATH]; + + if (filename_to_utf16 (fname, fname_w) != 0) + err = ERROR_FILE_NOT_FOUND; + else + result = SystemParametersInfoW (SPI_SETDESKWALLPAPER, 0, fname_w, + SPIF_SENDCHANGE); + } + else + { + char fname_a[MAX_PATH]; + + if (filename_to_ansi (fname, fname_a) != 0) + err = ERROR_FILE_NOT_FOUND; + else + result = SystemParametersInfoA (SPI_SETDESKWALLPAPER, 0, fname_a, + SPIF_SENDCHANGE); + } + if (!result) + { + if (err == ERROR_FILE_NOT_FOUND) + error ("Wallpaper file %s does not exist or cannot be accessed", fname); + else + { + err = GetLastError (); + if (err) + error ("Could not set desktop wallpaper: %s", w32_strerror (err)); + else + error ("Could not set desktop wallpaper (wrong image type?)"); + } + } + + return Qnil; +} +#endif + /*********************************************************************** Initialization ***********************************************************************/ @@ -10926,6 +10986,7 @@ keys when IME input is received. */); defsubr (&Sx_file_dialog); #ifdef WINDOWSNT defsubr (&Ssystem_move_file_to_trash); + defsubr (&Sw32_set_wallpaper); #endif } @@ -11179,6 +11240,8 @@ globals_of_w32fns (void) get_proc_addr (user32_lib, "EnumDisplayMonitors"); get_title_bar_info_fn = (GetTitleBarInfo_Proc) get_proc_addr (user32_lib, "GetTitleBarInfo"); + system_parameters_info_w_fn = (SystemParametersInfoW_Proc) + get_proc_addr (user32_lib, "SystemParametersInfoW"); { HMODULE imm32_lib = GetModuleHandle ("imm32.dll");