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.
This commit is contained in:
Eli Zaretskii 2022-09-15 14:51:31 +03:00
parent 6d61d6018c
commit 09e93c4daf
3 changed files with 73 additions and 12 deletions

View file

@ -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'.

View file

@ -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))

View file

@ -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");