]> code.delx.au - gnu-emacs/blobdiff - src/w32fns.c
* src/dispnew.c: Remove obsolete comment.
[gnu-emacs] / src / w32fns.c
index 70964cb8667730fd4eca7ea87bb87c7f36d7f191..bc310da0d2f83f02c1879bc99ab9457007f44dba 100644 (file)
@@ -1,6 +1,6 @@
 /* Graphical user interface functions for the Microsoft W32 API.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  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 <limits.h>
 #include <errno.h>
 #include <math.h>
+#include <setjmp.h>
 
 #include "lisp.h"
 #include "w32term.h"
@@ -46,6 +47,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "systime.h"
 #include "termhooks.h"
 #include "w32heap.h"
+#include "w32.h"
 
 #include "bitmaps/gray.xbm"
 
@@ -252,6 +254,9 @@ typedef BOOL (WINAPI * TrackMouseEvent_Proc)
 typedef LONG (WINAPI * ImmGetCompositionString_Proc)
   (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen);
 typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window);
+typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
+typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
+                                                     IN COMPOSITIONFORM *form);
 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
   (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
@@ -260,6 +265,8 @@ TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
 ImmGetContext_Proc get_ime_context_fn = NULL;
+ImmReleaseContext_Proc release_ime_context_fn = NULL;
+ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
 GetMonitorInfo_Proc get_monitor_info_fn = NULL;
 
@@ -2841,7 +2848,12 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
             EndPaint (hwnd, &paintStruct);
             leave_crit ();
 
-            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+           /* Change the message type to prevent Windows from
+              combining WM_PAINT messages in the Lisp thread's queue,
+              since Windows assumes that each message queue is
+              dedicated to one frame and does not bother checking
+              that hwnd matches before combining them.  */
+            my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
 
             return 0;
           }
@@ -3153,16 +3165,55 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
           buffer = alloca(size);
           size = get_composition_string_fn (context, GCS_RESULTSTR,
                                             buffer, size);
+         release_ime_context_fn (hwnd, context);
+
           signal_user_input ();
           for (i = 0; i < size / sizeof (wchar_t); i++)
             {
               my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
                            lParam);
             }
-          /* We output the whole string above, so ignore following ones
-             until we are notified of the end of composition.  */
-          ignore_ime_char = 1;
+          /* Ignore the messages for the rest of the
+            characters in the string that was output above.  */
+          ignore_ime_char = (size / sizeof (wchar_t)) - 1;
         }
+      else
+       ignore_ime_char--;
+
+      break;
+
+    case WM_IME_STARTCOMPOSITION:
+      if (!set_ime_composition_window_fn)
+       goto dflt;
+      else
+       {
+         COMPOSITIONFORM form;
+         HIMC context;
+         struct window *w;
+
+         if (!context)
+           break;
+
+         f = x_window_to_frame (dpyinfo, hwnd);
+         w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+
+         form.dwStyle = CFS_RECT;
+         form.ptCurrentPos.x = w32_system_caret_x;
+         form.ptCurrentPos.y = w32_system_caret_y;
+
+         form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
+         form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
+                            + WINDOW_HEADER_LINE_HEIGHT (w));
+         form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
+                              - WINDOW_RIGHT_MARGIN_WIDTH (w)
+                              - WINDOW_RIGHT_FRINGE_WIDTH (w));
+         form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+                               - WINDOW_MODE_LINE_HEIGHT (w));
+
+         context = get_ime_context_fn (hwnd);
+         set_ime_composition_window_fn (context, &form);
+         release_ime_context_fn (hwnd, context);
+       }
       break;
 
     case WM_IME_ENDCOMPOSITION:
@@ -5279,9 +5330,18 @@ w32_hide_hourglass ()
     {
       struct frame *f = x_window_to_frame (&one_w32_display_info,
                                           hourglass_hwnd);
+      if (f)
+       f->output_data.w32->hourglass_p = 0;
+      else
+       /* If frame was deleted, restore to selected frame's cursor.  */
+       f = SELECTED_FRAME ();
+
+      if (FRAME_W32_P (f))
+       SetCursor (f->output_data.w32->current_cursor);
+      else
+       /* No cursors on non GUI frames - restore to stock arrow cursor.  */
+       SetCursor (w32_load_cursor (IDC_ARROW));
 
-      f->output_data.w32->hourglass_p = 0;
-      SetCursor (f->output_data.w32->current_cursor);
       hourglass_shown_p = 0;
     }
 }
@@ -5368,6 +5428,10 @@ x_create_tip_frame (dpyinfo, parms, text)
 
   kb = dpyinfo->terminal->kboard;
 
+  /* The calls to x_get_arg remove elements from PARMS, so copy it to
+     avoid destructive changes behind our caller's back.  */
+  parms = Fcopy_alist (parms);
+
   /* Get the name of the frame to use for resource lookup.  */
   name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
@@ -5437,8 +5501,8 @@ x_create_tip_frame (dpyinfo, parms, text)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-  /* Perhaps, we must allow frame parameter, say `font-backend',
-     to specify which font backends to use.  */
+  if (uniscribe_available)
+    register_font_driver (&uniscribe_font_driver, f);
   register_font_driver (&w32font_driver, f);
 
   x_default_parameter (f, parms, Qfont_backend, Qnil,
@@ -6160,7 +6224,7 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
   if (!NILP (Ffile_directory_p (filename))
       && NILP (Ffile_symlink_p (filename)))
     {
-      operation = Qdelete_directory;
+      operation = intern ("delete-directory");
       filename = Fdirectory_file_name (filename);
     }
   filename = Fexpand_file_name (filename, Qnil);
@@ -6270,6 +6334,7 @@ an integer representing a ShowWindow flag:
      Lisp_Object operation, document, parameters, show_flag;
 {
   Lisp_Object current_dir;
+  char *errstr;
 
   CHECK_STRING (document);
 
@@ -6290,7 +6355,17 @@ an integer representing a ShowWindow flag:
                           XINT (show_flag) : SW_SHOWDEFAULT))
       > 32)
     return Qt;
-  error ("ShellExecute failed: %s", w32_strerror (0));
+  errstr = w32_strerror (0);
+  /* The error string might be encoded in the locale's encoding.  */
+  if (!NILP (Vlocale_coding_system))
+    {
+      Lisp_Object decoded =
+       code_convert_string_norecord (make_unibyte_string (errstr,
+                                                          strlen (errstr)),
+                                     Vlocale_coding_system, 0);
+      errstr = (char *)SDATA (decoded);
+    }
+  error ("ShellExecute failed: %s", errstr);
 }
 
 /* Lookup virtual keycode from string representing the name of a
@@ -6875,7 +6950,8 @@ frame_parm_handler w32_frame_parm_handlers[] =
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
   x_set_font_backend,
-  x_set_alpha
+  x_set_alpha,
+  0, /* x_set_sticky */
 };
 
 void
@@ -6908,9 +6984,9 @@ syms_of_w32fns ()
 
 
   Fput (Qundefined_color, Qerror_conditions,
-       Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
+       pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
   Fput (Qundefined_color, Qerror_message,
-       build_string ("Undefined color"));
+       make_pure_c_string ("Undefined color"));
 
   staticpro (&w32_grabbed_keys);
   w32_grabbed_keys = Qnil;
@@ -6995,7 +7071,7 @@ Set to nil to handle Caps Lock as the `capslock' key.  */);
 The value can be hyper, super, meta, alt, control or shift for the
 respective modifier, or nil to handle Scroll Lock as the `scroll' key.
 Any other value will cause the Scroll Lock key to be ignored.  */);
-  Vw32_scroll_lock_modifier = Qt;
+  Vw32_scroll_lock_modifier = Qnil;
 
   DEFVAR_LISP ("w32-lwindow-modifier",
               &Vw32_lwindow_modifier,
@@ -7260,6 +7336,10 @@ globals_of_w32fns ()
       GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
     get_ime_context_fn = (ImmGetContext_Proc)
       GetProcAddress (imm32_lib, "ImmGetContext");
+    release_ime_context_fn = (ImmReleaseContext_Proc)
+      GetProcAddress (imm32_lib, "ImmReleaseContext");
+    set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
+      GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
   }
   DEFVAR_INT ("w32-ansi-code-page",
              &w32_ansi_code_page,