]> git.eshelyaron.com Git - emacs.git/commitdiff
Revisited my earlier fix for the following entry in etc/PROBLEMS: 'Emacs built on...
authorBen Key <bkey1@tampabay.rr.com>
Wed, 18 Dec 2002 06:16:28 +0000 (06:16 +0000)
committerBen Key <bkey1@tampabay.rr.com>
Wed, 18 Dec 2002 06:16:28 +0000 (06:16 +0000)
src/ChangeLog
src/emacs.c
src/w32.c
src/w32.h
src/w32fns.c
src/w32menu.c
src/w32term.c

index ae7f978823380fceacf9c2db120d83ff37ea3624..f7fc7bb12531f26e94bed2790363594c912a6db7 100644 (file)
@@ -1,3 +1,88 @@
+2002-12-17  Ben Key <bkey1@tampabay.rr.com>
+       * Revisited my earlier fix for the following entry in
+       etc/PROBLEMS: 
+       "Emacs built on Windows 9x/ME crashes at startup on Windows XP,
+       or Emacs builtpart of on XP crashes at startup on Windows 9x/ME."
+       
+       These changes were in part based upon suggestions made by Peter
+       'Luna' Runestig [peter@runestig.com].
+
+       * w32.c (g_b_init_is_windows_9x, g_b_init_open_process_token,
+       g_b_init_get_token_information, g_b_init_lookup_account_sid,
+       g_b_init_get_sid_identifier_authority ): Added several static
+       global variables.
+
+       * w32.c (globals_of_w32): New function.  Used to initialize those
+       global variables that must always be initialized on startup even
+       when the global variable initialized is non zero.  Its primary
+       purpose at this time is to set the global variables
+       g_b_init_is_windows_9x, g_b_init_open_process_token,
+       g_b_init_get_token_information, g_b_init_lookup_account_sid, and
+       g_b_init_get_sid_identifier_authority to 0 on startup.  Called
+       from main.
+
+       * w32.c (is_windows_9x): Perform initialization only if
+       g_b_init_is_windows_9x is equal to 0.  On initialization set
+       g_b_init_is_windows_9x equal to 1.
+
+       * w32.c (open_process_token): Perform initialization only if
+       g_b_init_open_process_token is equal to 0.  On initialization set
+       g_b_init_open_process_token equal to 1.
+       
+       * w32.c (get_token_information): Perform initialization only if
+       g_b_init_get_token_information is equal to 0.  On initialization
+       set g_b_init_get_token_information equal to 1.
+       
+       * w32.c (lookup_account_sid): Perform initialization only if
+       g_b_init_lookup_account_sid is equal to 0.  On initialization 
+       set g_b_init_lookup_account_sid equal to 1.
+
+       * w32.c (get_sid_identifier_authority): Perform initialization
+       only if g_b_init_get_sid_identifier_authority is equal to 0.  On
+       initialization  set g_b_init_get_sid_identifier_authority equal to
+       1.
+
+       * w32fns.c (globals_of_w32fns): New function. Used to initialize
+       those global variables that must always be initialized on startup
+       even when the global variable initialized is non zero.  Its
+       primary purpose at this time is to initialize the global variable
+       track_mouse_event_fn.
+
+       * w32fns.c (w32_wnd_proc):  Remove initialization of
+       track_mouse_event_fn from the handler for the WM_SETFOCUS
+       message.
+
+       * w32fns.c (syms_of_w32fns): Call globals_of_w32fns.
+
+       * w32menu.c (globals_of_w32menu):  New function. Used to
+       initialize those global variables that must always be initialized
+       on startup even when the global variable initialized is non zero.
+       Its primary purpose at this time is to initialize the global
+       variables get_menu_item_info and set_menu_item_info.
+
+       * w32menu.c (initialize_frame_menubar): Remove initialization of
+       get_menu_item_info and set_menu_item_info.
+
+       * w32menu.c (syms_of_w32menu): Call globals_of_w32menu.
+
+       * w32.h (globals_of_w32, globals_of_w32fns, globals_of_w32menu):
+       Declare them.
+
+       * emacs.c (main): Call globals_of_w32 prior to calling
+       init_environment if WINDOWSNT is defined.  Call globals_of_w32fns
+       and globals_of_w32menu if initialized is non zero and HAVE_NTGUI
+       is defined.
+
+       * w32term.c (x_update_window_begin): Fix Windows API error
+       detected by BoundsChecker.  Test to determine if
+       w32_system_caret_hwnd is NULL prior to attempting to use
+       SendMessage to send the WM_EMACS_HIDE_CARET message to it.
+
+       * w32term.c (x_update_window_end): Fix Windows API error
+       detected by BoundsChecker.  Test to determine if
+       w32_system_caret_hwnd is NULL prior to attempting to use
+       SendMessage to send the WM_EMACS_SHOW_CARET message to it.
+       
 2002-12-17  Kenichi Handa  <handa@m17n.org>
 
        * coding.c (coding_system_require_warning): New variable.
index 7bbaac8f9239ceda1118b91199c4bc87d393931c..7b5830c06a0515684ed19049fda77bd9cdcb9ef4 100644 (file)
@@ -1375,6 +1375,7 @@ main (argc, argv
 #endif /* MSDOS */
 
 #ifdef WINDOWSNT
+  globals_of_w32 ();
   /* Initialize environment from registry settings.  */
   init_environment (argv);
   init_ntproc ();      /* must precede init_editfns.  */
@@ -1540,6 +1541,17 @@ main (argc, argv
       keys_of_keymap ();
       keys_of_minibuf ();
       keys_of_window ();
+    }
+       else
+    {
+      /*
+        Initialization that must be done even if the global variable
+        initialized is non zero
+      */
+#ifdef HAVE_NTGUI
+      globals_of_w32fns ();
+      globals_of_w32menu ();
+#endif  /* end #ifdef HAVE_NTGUI */
     }
 
   if (!noninteractive)
index a608aad36f4ec335f83a9fe16c18f521ed900f7d..57b0e28d0ca393c54cec97139fa0d11caf26a97a 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -99,12 +99,23 @@ Boston, MA 02111-1307, USA.
 #include "w32heap.h"
 #include "systime.h"
 
+void globals_of_w32 ();
+
 extern Lisp_Object Vw32_downcase_file_names;
 extern Lisp_Object Vw32_generate_fake_inodes;
 extern Lisp_Object Vw32_get_true_file_attributes;
 extern Lisp_Object Vw32_num_mouse_buttons;
 
 \f
+/*
+       Initialization states
+ */
+static BOOL g_b_init_is_windows_9x;
+static BOOL g_b_init_open_process_token;
+static BOOL g_b_init_get_token_information;
+static BOOL g_b_init_lookup_account_sid;
+static BOOL g_b_init_get_sid_identifier_authority;
+
 /*
   BEGIN: Wrapper functions around OpenProcessToken
   and other functions in advapi32.dll that are only
@@ -140,15 +151,19 @@ typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) (
   /* ** A utility function ** */
 static BOOL is_windows_9x ()
 {
-  BOOL b_ret=0;
+  static BOOL s_b_ret=0;
   OSVERSIONINFO os_ver;
-  ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
-  os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-  if (GetVersionEx (&os_ver))
+  if (g_b_init_is_windows_9x == 0)
     {
-      b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+      g_b_init_is_windows_9x = 1;
+      ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
+      os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+      if (GetVersionEx (&os_ver))
+        {
+          s_b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+        }
     }
-  return b_ret;
+  return s_b_ret;
 }
 
   /* ** The wrapper functions ** */
@@ -158,21 +173,25 @@ BOOL WINAPI open_process_token (
     DWORD DesiredAccess,
     PHANDLE TokenHandle)
 {
-  OpenProcessToken_Proc pfn_Open_Process_Token = NULL;
+  static OpenProcessToken_Proc s_pfn_Open_Process_Token = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Open_Process_Token =
-    (OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken");
-  if (pfn_Open_Process_Token == NULL)
+  if (g_b_init_open_process_token == 0)
+    {
+      g_b_init_open_process_token = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Open_Process_Token =
+        (OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken");
+    }
+  if (s_pfn_Open_Process_Token == NULL)
     {
       return FALSE;
     }
   return (
-      pfn_Open_Process_Token (
+      s_pfn_Open_Process_Token (
           ProcessHandle,
           DesiredAccess,
           TokenHandle)
@@ -186,21 +205,25 @@ BOOL WINAPI get_token_information (
     DWORD TokenInformationLength,
     PDWORD ReturnLength)
 {
-  GetTokenInformation_Proc pfn_Get_Token_Information = NULL;
+  static GetTokenInformation_Proc s_pfn_Get_Token_Information = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Get_Token_Information =
-    (GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation");
-  if (pfn_Get_Token_Information == NULL)
+  if (g_b_init_get_token_information == 0)
+    {
+      g_b_init_get_token_information = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Token_Information =
+        (GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation");
+    }
+  if (s_pfn_Get_Token_Information == NULL)
     {
       return FALSE;
     }
   return (
-      pfn_Get_Token_Information (
+      s_pfn_Get_Token_Information (
           TokenHandle,
           TokenInformationClass,
           TokenInformation,
@@ -218,21 +241,25 @@ BOOL WINAPI lookup_account_sid (
     LPDWORD cbDomainName,
     PSID_NAME_USE peUse)
 {
-  LookupAccountSid_Proc pfn_Lookup_Account_Sid = NULL;
+  static LookupAccountSid_Proc s_pfn_Lookup_Account_Sid = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Lookup_Account_Sid =
-    (LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name);
-  if (pfn_Lookup_Account_Sid == NULL)
+  if (g_b_init_lookup_account_sid == 0)
+    {
+      g_b_init_lookup_account_sid = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Lookup_Account_Sid =
+        (LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name);
+    }
+  if (s_pfn_Lookup_Account_Sid == NULL)
     {
       return FALSE;
     }
   return (
-      pfn_Lookup_Account_Sid (
+      s_pfn_Lookup_Account_Sid (
           lpSystemName,
           Sid,
           Name,
@@ -246,21 +273,25 @@ BOOL WINAPI lookup_account_sid (
 PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority (
     PSID pSid)
 {
-  GetSidIdentifierAuthority_Proc pfn_Get_Sid_Identifier_Authority = NULL;
+  static GetSidIdentifierAuthority_Proc s_pfn_Get_Sid_Identifier_Authority = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return NULL;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Get_Sid_Identifier_Authority =
-    (GetSidIdentifierAuthority_Proc) GetProcAddress (
-        hm_advapi32, "GetSidIdentifierAuthority");
-  if (pfn_Get_Sid_Identifier_Authority == NULL)
+  if (g_b_init_get_sid_identifier_authority == 0)
+    {
+      g_b_init_get_sid_identifier_authority = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Sid_Identifier_Authority =
+        (GetSidIdentifierAuthority_Proc) GetProcAddress (
+            hm_advapi32, "GetSidIdentifierAuthority");
+    }
+  if (s_pfn_Get_Sid_Identifier_Authority == NULL)
     {
       return NULL;
     }
-  return (pfn_Get_Sid_Identifier_Authority (pSid));
+  return (s_pfn_Get_Sid_Identifier_Authority (pSid));
 }
 
 /*
@@ -3909,4 +3940,18 @@ init_ntproc ()
   check_windows_init_file ();
 }
 
+/*
+       globals_of_w32 is used to initialize those global variables that
+       must always be initialized on startup even when the global variable
+       initialized is non zero (see the function main in emacs.c).
+*/
+void globals_of_w32 ()
+{
+  g_b_init_is_windows_9x = 0;
+  g_b_init_open_process_token = 0;
+  g_b_init_get_token_information = 0;
+  g_b_init_lookup_account_sid = 0;
+  g_b_init_get_sid_identifier_authority = 0;
+}
+
 /* end of nt.c */
index 24fda2c648b621e17adb9e4055eb7c0aa70d05a6..c8733c41a26d503dd07e222a46e84cc152caaebb 100644 (file)
--- a/src/w32.h
+++ b/src/w32.h
@@ -124,10 +124,13 @@ extern LPBYTE w32_get_resource (char * key, LPDWORD type);
 
 extern void init_ntproc ();
 extern void term_ntproc ();
+extern void globals_of_w32 ();
 extern void syms_of_w32term ();
 extern void syms_of_w32fns ();
+extern void globals_of_w32fns ();
 extern void syms_of_w32select ();
 extern void syms_of_w32menu ();
+extern void globals_of_w32menu ();
 extern void syms_of_fontset ();
 
 #endif /* EMACS_W32_H */
index 86984597e99453a4a37a505bd3a78d4af5ae782f..08d81d10296e8f45498d4c96ae5966bca4a49214 100644 (file)
@@ -55,6 +55,9 @@ Boston, MA 02111-1307, USA.  */
 #include <dlgs.h>
 #define FILE_NAME_TEXT_FIELD edt1
 
+void syms_of_w32fns ();
+void globals_of_w32fns ();
+
 extern void free_frame_menubar ();
 extern void x_compute_fringe_widths P_ ((struct frame *, int));
 extern double atof ();
@@ -4934,30 +4937,6 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       goto dflt;
 
     case WM_SETFOCUS:
-      /*
-        Reinitialize the function pointer track_mouse_event_fn here.
-        This is required even though it is initialized in syms_of_w32fns
-        which is called in main (emacs.c).
-        Reinitialize the function pointer track_mouse_event_fn here.
-        Even though this function pointer is initialized in
-        syms_of_w32fns which is called from main (emacs.c),
-        we need to initialize it again here in order to prevent
-        a crash that occurs in Windows 9x (possibly only when Emacs
-        was built on Windows NT / 2000 / XP?) when handling the
-        WM_MOUSEMOVE message.
-        The crash occurs when attempting to call the Win32 API
-        function TrackMouseEvent through the function pointer.
-        It appears as if the function pointer that is obtained when
-        syms_of_w32fns is called from main is no longer valid
-        (possibly due to DLL relocation?).
-        To resolve this issue, I have placed a call to reinitialize
-        this function pointer here because this message gets received
-        when the Emacs window gains focus.        
-       */
-      track_mouse_event_fn =
-        (TrackMouseEvent_Proc) GetProcAddress (
-            GetModuleHandle ("user32.dll"),
-            "TrackMouseEvent");
       dpyinfo->faked_key = 0;
       reset_modifiers ();
       register_hot_keys (hwnd);
@@ -14906,14 +14885,9 @@ If the underlying system call fails, value is nil.  */)
 void
 syms_of_w32fns ()
 {
-  HMODULE user32_lib = GetModuleHandle ("user32.dll");
-
-  /* This is zero if not using MS-Windows.  */
+       globals_of_w32fns ();
+       /* This is zero if not using MS-Windows.  */
   w32_in_use = 0;
-
-  /* TrackMouseEvent not available in all versions of Windows, so must load
-     it dynamically.  Do it once, here, instead of every time it is used.  */
-  track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
   track_mouse_window = NULL;
 
   w32_visible_system_caret_hwnd = NULL;
@@ -15496,7 +15470,26 @@ versions of Windows) characters.  */);
   defsubr (&Sx_file_dialog);
 }
 
+       
+/*
+       globals_of_w32fns is used to initialize those global variables that
+       must always be initialized on startup even when the global variable
+       initialized is non zero (see the function main in emacs.c).
+       globals_of_w32fns is called from syms_of_w32fns when the global
+       variable initialized is 0 and directly from main when initialized
+       is non zero.
+ */
+void globals_of_w32fns ()
+{
+  HMODULE user32_lib = GetModuleHandle ("user32.dll");
+       /*
+               TrackMouseEvent not available in all versions of Windows, so must load
+               it dynamically.  Do it once, here, instead of every time it is used.
+  */
+  track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
+}
 
+       
 void
 init_xfns ()
 {
index 8139a0ad956bdbe7e8c967100254acf4dfe3b588..e573986b31c5bf86a01dd0d5cde8508ce650afb0 100644 (file)
@@ -130,6 +130,7 @@ typedef struct _widget_value
 static HMENU current_popup_menu;
 
 void syms_of_w32menu ();
+void globals_of_w32menu ();
 
 typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
     IN HMENU,
@@ -1606,26 +1607,6 @@ void
 initialize_frame_menubar (f)
      FRAME_PTR f;
 {
-  HMODULE user32 = GetModuleHandle ("user32.dll");
-  /*
-    Reinitialize the function pointers set_menu_item_info and
-    get_menu_item_info here.
-    Even though these function pointers are initialized in
-    syms_of_w32menu which is called from main (emacs.c),
-    we need to initialize them again here in order to prevent
-    a crash that occurs in Windows 9x (possibly only when Emacs
-    was built on Windows NT / 2000 / XP?) in add_menu_item.
-    The crash occurs when attempting to call the Win32 API
-    function SetMenuItemInfo through the function pointer.
-    It appears as if the function pointer that is obtained when
-    syms_of_w32menu is called from main is no longer valid
-    (possibly due to DLL relocation?).
-    To resolve this issue, I have placed calls to reinitialize
-    these function pointers here because this function is the
-    entry point for menu creation.
-   */
-  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
-  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
   /* This function is called before the first chance to redisplay
      the frame.  It has to be, so the frame will have the right size.  */
   FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
@@ -2392,11 +2373,7 @@ w32_free_menu_strings (hwnd)
 
 void syms_of_w32menu ()
 {
-  /* See if Get/SetMenuItemInfo functions are available.  */
-  HMODULE user32 = GetModuleHandle ("user32.dll");
-  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
-  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
-
+       globals_of_w32menu ();
   staticpro (&menu_items);
   menu_items = Qnil;
 
@@ -2415,3 +2392,19 @@ The enable predicate for a menu command should check this variable.  */);
   defsubr (&Sx_popup_dialog);
 #endif
 }
+
+/*
+       globals_of_w32menu is used to initialize those global variables that
+       must always be initialized on startup even when the global variable
+       initialized is non zero (see the function main in emacs.c).
+       globals_of_w32menu is called from syms_of_w32menu when the global
+       variable initialized is 0 and directly from main when initialized
+       is non zero.
+ */
+void globals_of_w32menu ()
+{
+       /* See if Get/SetMenuItemInfo functions are available.  */
+  HMODULE user32 = GetModuleHandle ("user32.dll");
+  get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
+  set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
+}
index 73740b2555f4c827fef74d74dd8403d03dc30bc9..08b076df037d01bf28f834f297a88a1c15d73b3c 100644 (file)
@@ -603,8 +603,10 @@ x_update_window_begin (w)
   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
 
   /* Hide the system caret during an update.  */
-  if (w32_use_visible_system_caret)
-    SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
+  if (w32_use_visible_system_caret && w32_system_caret_hwnd)
+    {
+      SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
+    }
 
   updated_window = w;
   set_output_cursor (&w->cursor);
@@ -730,8 +732,10 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
   /* Unhide the caret.  This won't actually show the cursor, unless it
      was visible before the corresponding call to HideCaret in
      x_update_window_begin.  */
-  if (w32_use_visible_system_caret)
-    SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
+  if (w32_use_visible_system_caret && w32_system_caret_hwnd)
+    {
+      SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
+    }
 
   updated_window = NULL;
 }