]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement support for 'wallpaper-set' on MS-Windows
authorEli Zaretskii <eliz@gnu.org>
Thu, 15 Sep 2022 11:51:31 +0000 (14:51 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 15 Sep 2022 11:51:31 +0000 (14:51 +0300)
* 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
lisp/image/wallpaper.el
src/w32fns.c

index c88af4e90cf59bd39831e1cc86b6208a9c4e52ed..cc68cd82b8669b7b818cef6742689e24b6a89f97 100644 (file)
--- 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'.
index 2ebe5be033032aec5c275d859086fdca782be142..ef2ad31eba74368a9fa014c6ee964c14792f60ba 100644 (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))
index 745458d0a033c9306a8ce026147f0622b003a45e..d9070675a284738f6c7149afa556956a066ec06f 100644 (file)
@@ -10447,6 +10447,66 @@ w32_get_resource (const char *key, const char *name, LPDWORD lpdwtype)
   return (NULL);
 }
 \f
+#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");