emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 09e93c4daf: Implement support for 'wallpaper-set' on MS-Windows


From: Eli Zaretskii
Subject: master 09e93c4daf: Implement support for 'wallpaper-set' on MS-Windows
Date: Thu, 15 Sep 2022 07:52:57 -0400 (EDT)

branch: master
commit 09e93c4dafc6ffa3e556429757348adfa49a5a83
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    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.
---
 etc/NEWS                | 18 ++++++--------
 lisp/image/wallpaper.el |  4 +++-
 src/w32fns.c            | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 12 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index c88af4e90c..cc68cd82b8 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 2ebe5be033..ef2ad31eba 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 745458d0a0..d9070675a2 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");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]