Merge from emacs-24; up to 2012-12-21T07:35:02Z!ueno@gnu.org
[bpt/emacs.git] / src / w32fns.c
index 7459c4a..5fab2c9 100644 (file)
@@ -1,6 +1,6 @@
 /* Graphical user interface functions for the Microsoft Windows API.
 
-Copyright (C) 1989, 1992-201 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -27,6 +27,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <errno.h>
 #include <math.h>
 #include <fcntl.h>
+#include <unistd.h>
 
 #include "lisp.h"
 #include "w32term.h"
@@ -81,7 +82,6 @@ void syms_of_w32fns (void);
 void globals_of_w32fns (void);
 
 extern void free_frame_menubar (struct frame *);
-extern double atof (const char *);
 extern int w32_console_toggle_lock_key (int, Lisp_Object);
 extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
 extern void w32_free_menu_strings (HWND);
@@ -222,7 +222,7 @@ SYSTEM_INFO sysinfo_cache;
 /* This gives us version, build, and platform identification.  */
 OSVERSIONINFO osinfo_cache;
 
-unsigned long syspage_mask = 0;
+DWORD_PTR syspage_mask = 0;
 
 /* The major and minor versions of NT.  */
 int w32_major_version;
@@ -263,12 +263,8 @@ have_menus_p (void)
 FRAME_PTR
 check_x_frame (Lisp_Object frame)
 {
-  FRAME_PTR f;
+  struct frame *f = decode_live_frame (frame);
 
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
   if (! FRAME_W32_P (f))
     error ("Non-W32 frame used");
   return f;
@@ -307,19 +303,14 @@ check_x_display_info (Lisp_Object frame)
 /* Return the Emacs frame-object corresponding to an w32 window.
    It could be the frame's main window or an icon window.  */
 
-/* This function can be called during GC, so use GC_xxx type test macros.  */
-
 struct frame *
 x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
 {
   Lisp_Object tail, frame;
   struct frame *f;
 
-  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+  FOR_EACH_FRAME (tail, frame)
     {
-      frame = XCAR (tail);
-      if (!FRAMEP (frame))
-        continue;
       f = XFRAME (frame);
       if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
        continue;
@@ -1830,7 +1821,6 @@ static LRESULT CALLBACK w32_wnd_proc (HWND, UINT, WPARAM, LPARAM);
 static BOOL
 w32_init_class (HINSTANCE hinst)
 {
-
   if (w32_unicode_gui)
     {
       WNDCLASSW  uwc;
@@ -2088,8 +2078,35 @@ sync_modifiers (void)
 static int
 modifier_set (int vkey)
 {
-  if (vkey == VK_CAPITAL || vkey == VK_SCROLL)
-    return (GetKeyState (vkey) & 0x1);
+  /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
+     toggle keys is not an omission!  If you want to add it, you will
+     have to make changes in the default sub-case of the WM_KEYDOWN
+     switch, because if the NUMLOCK modifier is set, the code there
+     will directly convert any key that looks like an ASCII letter,
+     and also downcase those that look like upper-case ASCII.  */
+  if (vkey == VK_CAPITAL)
+    {
+      if (NILP (Vw32_enable_caps_lock))
+       return 0;
+      else
+       return (GetKeyState (vkey) & 0x1);
+    }
+  if (vkey == VK_SCROLL)
+    {
+      if (NILP (Vw32_scroll_lock_modifier)
+         /* w32-scroll-lock-modifier can be any non-nil value that is
+            not one of the modifiers, in which case it shall be ignored.  */
+         || !(   EQ (Vw32_scroll_lock_modifier, Qhyper)
+              || EQ (Vw32_scroll_lock_modifier, Qsuper)
+              || EQ (Vw32_scroll_lock_modifier, Qmeta)
+              || EQ (Vw32_scroll_lock_modifier, Qalt)
+              || EQ (Vw32_scroll_lock_modifier, Qcontrol)
+              || EQ (Vw32_scroll_lock_modifier, Qshift)))
+       return 0;
+      else
+       return (GetKeyState (vkey) & 0x1);
+    }
+
   if (!modifiers_recorded)
     return (GetKeyState (vkey) & 0x8000);
 
@@ -3939,6 +3956,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
        return retval;
       }
+    case WM_EMACS_FILENOTIFY:
+      my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+      return 1;
 
     default:
       /* Check for messages registered at runtime. */
@@ -4284,9 +4304,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   XSETFRAME (frame, f);
 
-  /* Note that Windows does support scroll bars.  */
-  FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
-
   /* By default, make scrollbars the system standard width. */
   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
 
@@ -4850,18 +4867,6 @@ x_pixel_height (register struct frame *f)
   return FRAME_PIXEL_HEIGHT (f);
 }
 
-int
-x_char_width (register struct frame *f)
-{
-  return FRAME_COLUMN_WIDTH (f);
-}
-
-int
-x_char_height (register struct frame *f)
-{
-  return FRAME_LINE_HEIGHT (f);
-}
-
 int
 x_screen_planes (register struct frame *f)
 {
@@ -5387,7 +5392,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   Finsert (1, &text);
   set_buffer_internal_1 (old_buffer);
 
-  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   record_unwind_protect (unwind_create_tip_frame, frame);
 
   /* By setting the output method, we're essentially saying that
@@ -5939,7 +5943,7 @@ Text larger than the specified size is clipped.  */)
                  SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 
     /* Let redisplay know that we have made the frame visible already.  */
-    f->async_visible = 1;
+    SET_FRAME_VISIBLE (f, 1);
 
     ShowWindow (FRAME_W32_WINDOW (f), SW_SHOWNOACTIVATE);
   }
@@ -6020,7 +6024,7 @@ typedef char guichar_t;
    read-only when "Directories" is selected in the filter.  This
    allows us to work around the fact that the standard Open File
    dialog does not support directories.  */
-static UINT CALLBACK
+static UINT_PTR CALLBACK
 file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
   if (msg == WM_NOTIFY)
@@ -6152,9 +6156,9 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
       filename = empty_unibyte_string;
 
 #ifdef CYGWIN
-    dir = Fcygwin_convert_path_to_windows (dir, Qt);
+    dir = Fcygwin_convert_file_name_to_windows (dir, Qt);
     if (SCHARS (filename) > 0)
-      filename = Fcygwin_convert_path_to_windows (filename, Qnil);
+      filename = Fcygwin_convert_file_name_to_windows (filename, Qnil);
 #endif
 
     CHECK_STRING (dir);
@@ -6250,12 +6254,12 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
             /* we get one of the two final 0 bytes for free. */
             1 + sizeof (wchar_t) * wcslen (filename_buf)));
 #else /* !NTGUI_UNICODE */
-        dostounix_filename (filename_buf);
+        dostounix_filename (filename_buf, 0);
         filename = DECODE_FILE (build_string (filename_buf));
 #endif /* NTGUI_UNICODE */
 
 #ifdef CYGWIN
-        filename = Fcygwin_convert_path_from_windows (filename, Qt);
+        filename = Fcygwin_convert_file_name_from_windows (filename, Qt);
 #endif /* CYGWIN */
 
         /* Strip the dummy filename off the end of the string if we
@@ -6480,12 +6484,12 @@ w32_parse_hot_key (Lisp_Object key)
 
   CHECK_VECTOR (key);
 
-  if (XFASTINT (Flength (key)) != 1)
+  if (ASIZE (key) != 1)
     return Qnil;
 
   GCPRO1 (key);
 
-  c = Faref (key, make_number (0));
+  c = AREF (key, 0);
 
   if (CONSP (c) && lucid_event_type_list_p (c))
     c = Fevent_convert_list (c);
@@ -7022,6 +7026,9 @@ cache_system_info (void)
       DWORD data;
     } version;
 
+  /* Cache the module handle of Emacs itself.  */
+  hinst = GetModuleHandle (NULL);
+
   /* Cache the version of the operating system.  */
   version.data = GetVersion ();
   w32_major_version = version.info.major;
@@ -7034,7 +7041,7 @@ cache_system_info (void)
 
   /* Cache page size, allocation unit, processor type, etc.  */
   GetSystemInfo (&sysinfo_cache);
-  syspage_mask = sysinfo_cache.dwPageSize - 1;
+  syspage_mask = (DWORD_PTR)sysinfo_cache.dwPageSize - 1;
 
   /* Cache os info.  */
   osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
@@ -7753,12 +7760,19 @@ emacs_abort (void)
 
        if (i)
          {
+#ifdef CYGWIN
+           int stderr_fd = 2;
+#else
            HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
-           int stderr_fd = -1, errfile_fd = -1;
+           int stderr_fd = -1;
+#endif
+           int errfile_fd = -1;
            int j;
 
+#ifndef CYGWIN
            if (errout && errout != INVALID_HANDLE_VALUE)
              stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY);
+#endif
            if (stderr_fd >= 0)
              write (stderr_fd, "\r\nBacktrace:\r\n", 14);
            errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
@@ -7775,7 +7789,7 @@ emacs_abort (void)
                /* stack[] gives the return addresses, whereas we want
                   the address of the call, so decrease each address
                   by approximate size of 1 CALL instruction.  */
-               sprintf (buf, "0x%p\r\n", stack[j] - sizeof(void *));
+               sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *));
                if (stderr_fd >= 0)
                  write (stderr_fd, buf, strlen (buf));
                if (errfile_fd >= 0)