]> code.delx.au - gnu-emacs/blobdiff - src/w32fns.c
Fix removal of variables from process-environment
[gnu-emacs] / src / w32fns.c
index 4be322182ce93ea69e2321aaf6b6cc5efac3f4a4..c57b5a188b238832858815a76a548db49c8dc8cf 100644 (file)
@@ -1,13 +1,13 @@
 /* Graphical user interface functions for the Microsoft Windows API.
 
-Copyright (C) 1989, 1992-2015 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-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
@@ -3154,9 +3154,45 @@ deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam,
              SHORT r = VkKeyScanW (*b), bitmap = 0x1FF;
 
              FPRINTF_WM_CHARS((stderr, "VkKeyScanW %#06x %#04x\n", (int)r,
-                              wParam));
+                               wParam));
              if ((r & 0xFF) == wParam)
                bitmap = r>>8; /* *b is reachable via simple interface */
+             else
+               {
+                 /* VkKeyScanW() (essentially) returns the FIRST key with
+                    the specified character; so here the pressed key is the
+                    SECONDARY key producing the character.
+
+                    Essentially, we have no information about the "role" of
+                    modifiers on this key: which contribute into the
+                    produced character (so "are consumed"), and which are
+                    "extra" (must attache to bindable events).
+
+                    The default above would consume ALL modifiers, so the
+                    character is reported "as is".  However, on many layouts
+                    the ordering of the keys (in the layout table) is not
+                    thought out well, so the "secondary" keys are often those
+                    which the users would prefer to use with Alt-CHAR.
+                    (Moreover - with e.g. Czech-QWERTY - the ASCII
+                    punctuation is accessible from two equally [nu]preferable
+                    AltGr-keys.)
+
+                    SO:   Heuristic: if the reported char is ASCII, AND Meta
+                    modifier is a candidate, behave as if Meta is present
+                    (fallback to the legacy branch; bug#23251).
+
+                    (This would break layouts
+                    - delivering ASCII characters
+                    - on SECONDARY keys
+                    - with not Shift/AltGr-like modifier combinations.
+                    All 3 conditions together must be pretty exotic
+                    cases - and a workaround exists: use "primary" keys!) */
+                 if (*b < 0x80
+                     && (wmsg.dwModifiers
+                         & (alt_modifier | meta_modifier
+                            | super_modifier | hyper_modifier)))
+                   return 0;
+               }
              if (*type_CtrlAlt == 'a') /* Simple Alt seen */
                {
                  if ((bitmap & ~1) == 0) /* 1: KBDSHIFT */
@@ -5207,7 +5243,7 @@ x_get_focus_frame (struct frame *frame)
 
 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
        doc: /* Internal function called by `color-defined-p', which see.
-(Note that the Nextstep version of this function ignores FRAME.)  */)
+\(Note that the Nextstep version of this function ignores FRAME.)  */)
   (Lisp_Object color, Lisp_Object frame)
 {
   XColor foo;
@@ -5349,7 +5385,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
        doc: /* Return the "vendor ID" string of the GUI software on TERMINAL.
 
-(Labeling every distributor as a "vendor" embodies the false assumption
+\(Labeling every distributor as a "vendor" embodies the false assumption
 that operating systems cannot be developed and distributed noncommercially.)
 
 For GNU and Unix systems, this queries the X server software; for
@@ -5751,7 +5787,7 @@ DISPLAY is the name of the display to connect to.
 Optional second arg XRM-STRING is a string of resources in xrdb format.
 If the optional third arg MUST-SUCCEED is non-nil,
 terminate Emacs if we can't open the connection.
-(In the Nextstep version, the last two arguments are currently ignored.)  */)
+\(In the Nextstep version, the last two arguments are currently ignored.)  */)
   (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
 {
   char *xrm_option;
@@ -6984,12 +7020,12 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
            if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                    SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                              SSDATA (prompt), -1, prompt_w, len);
       }
     else
@@ -7002,12 +7038,12 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
            if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0)
              report_file_error ("filename too long", default_filename);
          }
-       len = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                    SSDATA (prompt), -1, NULL, 0);
        if (len > 32768)
          len = 32768;
        prompt_w = alloca (len * sizeof (wchar_t));
-       pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+       pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                              SSDATA (prompt), -1, prompt_w, len);
        len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
        if (len > 32768)
@@ -7489,10 +7525,10 @@ a ShowWindow flag:
   current_dir = ENCODE_FILE (current_dir);
   /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could
      be a URL that is not limited to MAX_PATH chararcters.  */
-  doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+  doclen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                 SSDATA (document), -1, NULL, 0);
   doc_w = xmalloc (doclen * sizeof (wchar_t));
-  pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+  pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                        SSDATA (document), -1, doc_w, doclen);
   if (use_unicode)
     {
@@ -7507,12 +7543,12 @@ a ShowWindow flag:
          int len;
 
          parameters = ENCODE_SYSTEM (parameters);
-         len = pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+         len = pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
                                      SSDATA (parameters), -1, NULL, 0);
          if (len > 32768)
            len = 32768;
          params_w = alloca (len * sizeof (wchar_t));
-         pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+         pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
                                SSDATA (parameters), -1, params_w, len);
          params_w[len - 1] = 0;
        }
@@ -8090,14 +8126,25 @@ DEFUN ("w32-set-mouse-absolute-pixel-position", Fw32_set_mouse_absolute_pixel_po
        Sw32_set_mouse_absolute_pixel_position, 2, 2, 0,
        doc: /* Move mouse pointer to absolute pixel position (X, Y).
 The coordinates X and Y are interpreted in pixels relative to a position
-(0, 0) of the selected frame's display.  */)
+\(0, 0) of the selected frame's display.  */)
   (Lisp_Object x, Lisp_Object y)
 {
+  UINT trail_num = 0;
+  BOOL ret = false;
+
   CHECK_TYPE_RANGED_INTEGER (int, x);
   CHECK_TYPE_RANGED_INTEGER (int, y);
 
   block_input ();
+  /* When "mouse trails" are in effect, moving the mouse cursor
+     sometimes leaves behind an annoying "ghost" of the pointer.
+     Avoid that by momentarily switching off mouse trails.  */
+  if (os_subtype == OS_NT
+      && w32_major_version + w32_minor_version >= 6)
+    ret = SystemParametersInfo (SPI_GETMOUSETRAILS, 0, &trail_num, 0);
   SetCursorPos (XINT (x), XINT (y));
+  if (ret)
+    SystemParametersInfo (SPI_SETMOUSETRAILS, trail_num, NULL, 0);
   unblock_input ();
 
   return Qnil;
@@ -8948,7 +8995,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
         later versions support up to 128.  */
       if (nidw.cbSize == MYNOTIFYICONDATAW_V1_SIZE)
        {
-         tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                         tip, utf8_mbslen_lim (tip, 63),
                                         tipw, 64);
          if (tiplen >= 63)
@@ -8956,7 +9003,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
        }
       else
        {
-         tiplen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                         tip, utf8_mbslen_lim (tip, 127),
                                         tipw, 128);
          if (tiplen >= 127)
@@ -8975,7 +9022,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
        {
          int slen;
 
-         slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                             msg, utf8_mbslen_lim (msg, 255),
                                             msgw, 256);
          if (slen >= 255)
@@ -8988,7 +9035,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
            }
          wcscpy (nidw.szInfo, msgw);
          nidw.uTimeout = timeout;
-         slen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+         slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
                                       title, utf8_mbslen_lim (title, 63),
                                       titlew, 64);
          if (slen >= 63)
@@ -9659,6 +9706,12 @@ static PVOID except_addr;
 
 /* Stack overflow recovery.  */
 
+/* MinGW headers don't declare this (should be in malloc.h).  Also,
+   the function is not present pre-W2K, so make the call through
+   a function pointer.  */
+typedef int (__cdecl *_resetstkoflw_proc) (void);
+static _resetstkoflw_proc resetstkoflw;
+
 /* Re-establish the guard page at stack limit.  This is needed because
    when a stack overflow is detected, Windows removes the guard bit
    from the guard page, so if we don't re-establish that protection,
@@ -9666,12 +9719,14 @@ static PVOID except_addr;
 void
 w32_reset_stack_overflow_guard (void)
 {
-  /* MinGW headers don't declare this (should be in malloc.h).  */
-  _CRTIMP int __cdecl _resetstkoflw (void);
-
+  if (resetstkoflw == NULL)
+    resetstkoflw =
+      (_resetstkoflw_proc)GetProcAddress (GetModuleHandle ("msvcrt.dll"),
+                                         "_resetstkoflw");
   /* We ignore the return value.  If _resetstkoflw fails, the next
      stack overflow will crash the program.  */
-  (void)_resetstkoflw ();
+  if (resetstkoflw != NULL)
+    (void)resetstkoflw ();
 }
 
 static void
@@ -9902,6 +9957,7 @@ globals_of_w32fns (void)
   except_addr = 0;
 #ifndef CYGWIN
   prev_exception_handler = SetUnhandledExceptionFilter (my_exception_handler);
+  resetstkoflw = NULL;
 #endif
 
   DEFVAR_INT ("w32-ansi-code-page",