]> code.delx.au - gnu-emacs/blobdiff - nt/runemacs.c
Merge from origin/emacs-25
[gnu-emacs] / nt / runemacs.c
index 6cb145e9ef65abe72a6efa390cbd0e0d32a9fdca..9edf148348e3ace290f2144722f1959153c3714a 100644 (file)
@@ -1,12 +1,13 @@
-/* Copyright (C) 2001-2011
-     Free Software Foundation, Inc.
+/* runemacs --- Simple program to start Emacs with its console window hidden.
+
+Copyright (C) 2001-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -44,6 +45,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <malloc.h>
 
 static void set_user_model_id (void);
+static int ensure_unicows_dll (void);
 
 int WINAPI
 WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
@@ -57,6 +59,10 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
   char *new_cmdline;
   char *p;
   char modname[MAX_PATH];
+  static const char iconic_opt[] = "--iconic ", maximized_opt[] = "--maximized ";
+
+  if (!ensure_unicows_dll ())
+    goto error;
 
   set_user_model_id ();
 
@@ -66,10 +72,21 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
     goto error;
   *p = 0;
 
-  new_cmdline = alloca (MAX_PATH + strlen (cmdline) + 3);
+  new_cmdline = alloca (MAX_PATH
+                       + strlen (cmdline)
+                       + ((nShow == SW_SHOWMINNOACTIVE
+                           || nShow == SW_SHOWMAXIMIZED)
+                          ? max (sizeof (iconic_opt), sizeof (maximized_opt))
+                          : 0)
+                       + 3);
   /* Quote executable name in case of spaces in the path. */
   *new_cmdline = '"';
   strcpy (new_cmdline + 1, modname);
+  /* Detect and handle un-installed runemacs.exe in nt/ subdirectory,
+     while emacs.exe is in src/.  */
+  if ((p = strrchr (new_cmdline, '\\')) != NULL
+      && stricmp (p, "\\nt") == 0)
+    strcpy (p, "\\src");
 
 #ifdef CHOOSE_NEWEST_EXE
   {
@@ -106,7 +123,7 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
 #endif
 
   /* Append original arguments if any; first look for arguments we
-     recognise (-wait, -high, and -low), and apply them ourselves.  */
+     recognize (-wait, -high, and -low), and apply them ourselves.  */
   while (cmdline[0] == '-' || cmdline[0] == '/')
     {
       if (strncmp (cmdline+1, "wait", 4) == 0)
@@ -130,6 +147,14 @@ WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
       while (*++cmdline == ' ');
     }
 
+  /* If the desktop shortcut properties tell to invoke runemacs
+     minimized, or if they invoked runemacs via "start /min", pass
+     '--iconic' to Emacs, as that's what users will expect.  Likewise
+     with invoking runemacs maximized: pass '--maximized' to Emacs.  */
+  if (nShow == SW_SHOWMINNOACTIVE)
+    strcat (new_cmdline, iconic_opt);
+  else if (nShow == SW_SHOWMAXIMIZED)
+    strcat (new_cmdline, maximized_opt);
   strcat (new_cmdline, cmdline);
 
   /* Set emacs_dir variable if runemacs was in "%emacs_dir%\bin".  */
@@ -178,7 +203,7 @@ void
 set_user_model_id (void)
 {
   HMODULE shell;
-  HRESULT (WINAPI * set_user_model) (wchar_t * id);
+  HRESULT (WINAPI * set_user_model) (const wchar_t * id);
 
   /* On Windows 7 and later, we need to set the user model ID
      to associate emacsclient launched files with Emacs frames
@@ -202,3 +227,41 @@ set_user_model_id (void)
     }
 }
 
+static int
+ensure_unicows_dll (void)
+{
+  OSVERSIONINFO os_ver;
+  HMODULE h;
+
+  ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
+  os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+  if (!GetVersionEx (&os_ver))
+    return 0;
+
+  if (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+    {
+      h = LoadLibrary ("Unicows.dll");
+      if (!h)
+       {
+         int button;
+
+         button = MessageBox (NULL,
+                              "Emacs cannot load the UNICOWS.DLL library.\n"
+                              "This library is essential for using Emacs\n"
+                              "on this system.  You need to install it.\n\n"
+                              "Emacs will exit when you click OK.",
+                              "Emacs cannot load UNICOWS.DLL",
+                              MB_ICONERROR | MB_TASKMODAL
+                              | MB_SETFOREGROUND | MB_OK);
+         switch (button)
+           {
+             case IDOK:
+             default:
+               return 0;
+           }
+       }
+      FreeLibrary (h);
+      return 1;
+    }
+  return 1;
+}