]> code.delx.au - gnu-emacs/blobdiff - src/w32fns.c
Merge latest Org fixes (commit 7524ef2).
[gnu-emacs] / src / w32fns.c
index 7f0e6d5e5bfd1b954c725c6ea7387356e132aed6..289b1e6043c71254ae180062dfa14969613a440d 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.
 
@@ -45,7 +45,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "systime.h"
 #include "termhooks.h"
 
+#include "w32common.h"
+
+#ifdef WINDOWSNT
 #include "w32heap.h"
+#endif /* WINDOWSNT */
 
 #if CYGWIN
 #include "cygw32.h"
@@ -76,7 +80,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);
@@ -207,7 +210,7 @@ static void w32_show_hourglass (struct frame *);
 static void w32_hide_hourglass (void);
 
 #ifdef WINDOWSNT
-/* From w32inevet.c */
+/* From w32inevt.c */
 extern int faked_key;
 #endif /* WINDOWSNT */
 
@@ -217,7 +220,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;
@@ -697,7 +700,7 @@ DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
 }
 
 static Lisp_Object
-w32_color_map_lookup (char *colorname)
+w32_color_map_lookup (const char *colorname)
 {
   Lisp_Object tail, ret = Qnil;
 
@@ -776,7 +779,7 @@ add_system_logical_colors_to_map (Lisp_Object *system_colors)
 
 
 static Lisp_Object
-x_to_w32_color (char * colorname)
+x_to_w32_color (const char * colorname)
 {
   register Lisp_Object ret = Qnil;
 
@@ -785,11 +788,10 @@ x_to_w32_color (char * colorname)
   if (colorname[0] == '#')
     {
       /* Could be an old-style RGB Device specification.  */
-      char *color;
-      int size;
-      color = colorname + 1;
+      int size = strlen (colorname + 1);
+      char *color = alloca (size + 1);
 
-      size = strlen (color);
+      strcpy (color, colorname + 1);
       if (size == 3 || size == 6 || size == 9 || size == 12)
        {
          UINT colorval;
@@ -843,7 +845,7 @@ x_to_w32_color (char * colorname)
     }
   else if (strnicmp (colorname, "rgb:", 4) == 0)
     {
-      char *color;
+      const char *color;
       UINT colorval;
       int i, pos;
       pos = 0;
@@ -899,7 +901,7 @@ x_to_w32_color (char * colorname)
   else if (strnicmp (colorname, "rgbi:", 5) == 0)
     {
       /* This is an RGB Intensity specification.  */
-      char *color;
+      const char *color;
       UINT colorval;
       int i, pos;
       pos = 0;
@@ -2330,7 +2332,9 @@ w32_name_of_message (UINT msg)
 }
 #endif /* EMACSDEBUG */
 
-/* Here's an overview of how Emacs input works on MS-Windows.
+/* Here's an overview of how Emacs input works in GUI sessions on
+   MS-Windows.  (For description of non-GUI input, see the commentary
+   before w32_console_read_socket in w32inevt.c.)
 
    System messages are read and processed by w32_msg_pump below.  This
    function runs in a separate thread.  It handles a small number of
@@ -2419,7 +2423,7 @@ w32_msg_pump (deferred_msg * msg_buf)
                  thread-safe.  The next line is okay because the cons
                  cell is never made into garbage and is not relocated by
                  GC.  */
-             XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
+             XSETCAR (XIL ((EMACS_INT) msg.lParam), Qnil);
              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
                emacs_abort ();
              break;
@@ -2427,7 +2431,7 @@ w32_msg_pump (deferred_msg * msg_buf)
              {
                int vk_code = (int) msg.wParam;
                int cur_state = (GetKeyState (vk_code) & 1);
-               Lisp_Object new_state = (Lisp_Object) ((EMACS_INT) msg.lParam);
+               Lisp_Object new_state = XIL ((EMACS_INT) msg.lParam);
 
                /* NB: This code must be thread-safe.  It is safe to
                    call NILP because symbols are not relocated by GC,
@@ -3326,7 +3330,19 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         versions, there is no way of telling when the mouse leaves the
         frame, so we just have to put up with help-echo and mouse
         highlighting remaining while the frame is not active.  */
-      if (track_mouse_event_fn && !track_mouse_window)
+      if (track_mouse_event_fn && !track_mouse_window
+         /* If the menu bar is active, turning on tracking of mouse
+            movement events might send these events to the tooltip
+            frame, if the user happens to move the mouse pointer over
+            the tooltip.  But since we don't process events for
+            tooltip frames, this causes Windows to present a
+            hourglass cursor, which is ugly and unexpected.  So don't
+            enable tracking mouse events in this case; they will be
+            restarted when the menu pops down.  (Confusingly, the
+            menubar_active member of f->output_data.w32, tested
+            above, is only set when a menu was popped up _not_ from
+            the frame's menu bar, but via x-popup-menu.)  */
+         && !menubar_in_use)
        {
          TRACKMOUSEEVENT tme;
          tme.cbSize = sizeof (tme);
@@ -4639,22 +4655,14 @@ If omitted or nil, that stands for the selected frame's display.  */)
   (Lisp_Object display)
 {
   struct w32_display_info *dpyinfo = check_x_display_info (display);
-  HDC hdc;
   int cap;
 
-  hdc = GetDC (dpyinfo->root_window);
-  if (dpyinfo->has_palette)
-    cap = GetDeviceCaps (hdc, SIZEPALETTE);
-  else
-    cap = GetDeviceCaps (hdc, NUMCOLORS);
-
-  /* We force 24+ bit depths to 24-bit, both to prevent an overflow
-     and because probably is more meaningful on Windows anyway */
-  if (cap < 0)
-    cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
-
-  ReleaseDC (dpyinfo->root_window, hdc);
+  /* Don't use NCOLORS: it returns incorrect results under remote
+   * desktop.  We force 24+ bit depths to 24-bit, both to prevent an
+   * overflow and because probably is more meaningful on Windows
+   * anyway.  */
 
+  cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
   return make_number (cap);
 }
 
@@ -6010,7 +6018,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)
@@ -6112,7 +6120,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
   } new_file_details;
 
 #ifdef NTGUI_UNICODE
-  wchar_t filename_buf[MAX_PATH + 1];
+  wchar_t filename_buf[32*1024 + 1]; // NT kernel maximum
   OPENFILENAMEW * file_details = &new_file_details.details;
 #else /* not NTGUI_UNICODE */
   char filename_buf[MAX_PATH + 1];
@@ -6128,8 +6136,8 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 
     /* Note: under NTGUI_UNICODE, we do _NOT_ use ENCODE_FILE: the
        system file encoding expected by the platform APIs (e.g. Cygwin's
-       POSIX implementation) may not the same as the encoding expected
-       by the Windows API!  */
+       POSIX implementation) may not be the same as the encoding expected
+       by the Windows "ANSI" APIs!  */
 
     CHECK_STRING (prompt);
     CHECK_STRING (dir);
@@ -6142,9 +6150,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);
@@ -6174,11 +6182,12 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
     unixtodos_filename (SDATA (filename));
 #endif /* NTGUI_UNICODE */
 
-    /* Fill in the structure for the call to GetOpenFileName below.  For
-       NTGUI_UNICODE builds (which run only on NT), we just use the
-       actual size of the structure.  For non-NTGUI_UNICODE builds, we
-       tell the OS we're using an old version of the structure if it's not
-       new enough to support the newer version.  */
+    /* Fill in the structure for the call to GetOpenFileName below.
+       For NTGUI_UNICODE builds (which run only on NT), we just use
+       the actual size of the structure.  For non-NTGUI_UNICODE
+       builds, we tell the OS we're using an old version of the
+       structure if the OS isn't new enough to support the newer
+       version.  */
     memset (&new_file_details, 0, sizeof (new_file_details));
 
     if (w32_major_version > 4 && w32_major_version < 95)
@@ -6188,7 +6197,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 
     /* Set up the inout parameter for the selected file name.  */
     if (SBYTES (filename) + 1 > sizeof (filename_buf))
-      error ("filename too long");
+      report_file_error ("filename too long", default_filename);
 
     memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1);
     file_details->lpstrFile = filename_buf;
@@ -6215,6 +6224,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 
     {
       int count = SPECPDL_INDEX ();
+      /* Prevent redisplay.  */
       specbind (Qinhibit_redisplay, Qt);
       block_input ();
       file_details->lpfnHook = file_dialog_callback;
@@ -6243,7 +6253,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 #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
@@ -6986,8 +6996,10 @@ w32_strerror (int error_no)
   return buf;
 }
 
-/* For convenience when debugging.  */
-int
+/* For convenience when debugging.  (You cannot call GetLastError
+   directly from GDB: it will crash, because it uses the __stdcall
+   calling convention, not the _cdecl convention assumed by GDB.)  */
+DWORD
 w32_last_error (void)
 {
   return GetLastError ();
@@ -7020,7 +7032,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);
@@ -7710,4 +7722,3 @@ emacs_abort (void)
       break;
     }
 }
-