* w32fns.c (hourglass_timer, hourglass_hwnd): New variables.
authorJason Rumney <jasonr@gnu.org>
Wed, 19 Mar 2008 17:04:18 +0000 (17:04 +0000)
committerJason Rumney <jasonr@gnu.org>
Wed, 19 Mar 2008 17:04:18 +0000 (17:04 +0000)
(syms_of_w32fns): Initialize them.
(HOURGLASS_ID): New constant.
(x_window_to_frame): Don't check hourglass_window.
(w32_wnd_proc) <WM_TIMER>: Handle hourglass_timer.
(w32_wnd_proc) <WM_EXITMENULOOP>: Set pending hourglass cursor.
(w32_wnd_proc) <WM_SETCURSOR>: Set the hourglass or current cursor.
(w32_wnd_proc) <WM_EMACS_SETCURSOR>: Set frame's current_cursor.
Only change the cursor if hourglass is not active.
(Fx_create_frame): Initialize frame's current_cursor.
(hourglass_atimer): Remove.
(hourglass_started): New function.
(start_hourglass, cancel_hourglass, hide_hourglass): Adapt to w32.
(show_hourglass): Adapt to w32, changing argument to frame.

* w32term.h (struct w32_output): Remove hourglass_window.
Add current_cursor.

* eval.c (call_debugger, Fsignal):
* keyboard.c (recursive_edit_1, cmd_error, Ftop_level)
(command_loop_1, Fread_key_sequence, Fread_key_sequence_vector)
(Fexecute_extended_command, cancel_hourglass_unwind):
* minibuf.c (read_minibuf):
* fns.c (Fy_or_n_p): Enable hourglass when HAVE_WINDOW_SYSTEM.

src/ChangeLog
src/eval.c
src/fns.c
src/keyboard.c
src/minibuf.c
src/w32fns.c
src/w32term.h

index 875e8b7..9fd8d69 100644 (file)
@@ -1,12 +1,29 @@
-2008-03-19  Stefan Monnier  <monnier@iro.umontreal.ca>
-
-       * window.c (run_funs): New fun.
-       (run_window_configuration_change_hook): Use it to run the buffer-local
-       and the global part of the hook.
-
-       * xdisp.c (format_mode_line_unwind_data): Add window argument.
-       (unwind_format_mode_line): Restore selected window.
-       (x_consider_frame_title, Fformat_mode_line): Set selected window.
+2008-03-19  Jason Rumney  <jasonr@gnu.org>
+
+       * w32fns.c (hourglass_timer, hourglass_hwnd): New variables.
+       (syms_of_w32fns): Initialize them.
+       (HOURGLASS_ID): New constant.
+       (x_window_to_frame): Don't check hourglass_window.
+       (w32_wnd_proc) <WM_TIMER>: Handle hourglass_timer.
+       (w32_wnd_proc) <WM_EXITMENULOOP>: Set pending hourglass cursor.
+       (w32_wnd_proc) <WM_SETCURSOR>: Set the hourglass or current cursor.
+       (w32_wnd_proc) <WM_EMACS_SETCURSOR>: Set frame's current_cursor.
+       Only change the cursor if hourglass is not active.
+       (Fx_create_frame): Initialize frame's current_cursor.
+       (hourglass_atimer): Remove.
+       (hourglass_started): New function.
+       (start_hourglass, cancel_hourglass, hide_hourglass): Adapt to w32.
+       (show_hourglass): Adapt to w32, changing argument to frame.
+
+       * w32term.h (struct w32_output): Remove hourglass_window.
+       Add current_cursor.
+
+       * eval.c (call_debugger, Fsignal):
+       * keyboard.c (recursive_edit_1, cmd_error, Ftop_level)
+       (command_loop_1, Fread_key_sequence, Fread_key_sequence_vector)
+       (Fexecute_extended_command, cancel_hourglass_unwind):
+       * minibuf.c (read_minibuf):
+       * fns.c (Fy_or_n_p): Enable hourglass when HAVE_WINDOW_SYSTEM.
 
 2008-03-17  Stefan Monnier  <monnier@iro.umontreal.ca>
 
index 38cf87b..62fe015 100644 (file)
@@ -283,7 +283,7 @@ call_debugger (arg)
   if (SPECPDL_INDEX () + 100 > max_specpdl_size)
     max_specpdl_size = SPECPDL_INDEX () + 100;
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -1640,7 +1640,7 @@ See also the function `condition-case'.  */)
 
 #if 0 /* rms: I don't know why this was here,
         but it is surely wrong for an error that is handled.  */
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
index e0da65a..e89fbbc 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -2600,7 +2600,7 @@ is nil and `use-dialog-box' is non-nil.  */)
   xprompt = prompt;
   GCPRO2 (prompt, xprompt);
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
index 16b9006..cdcf4c6 100644 (file)
@@ -935,7 +935,7 @@ recursive_edit_1 ()
       specbind (Qstandard_input, Qt);
     }
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   /* The command loop has started an hourglass timer, so we have to
      cancel it here, otherwise it will fire because the recursive edit
      can take some time.  Do not check for display_hourglass_p here,
@@ -1220,7 +1220,7 @@ cmd_error (data)
   Lisp_Object old_level, old_length;
   char macroerror[50];
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -1396,7 +1396,7 @@ DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
        doc: /* Exit all recursive editing levels.  */)
      ()
 {
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -1519,7 +1519,7 @@ static void adjust_point_for_property P_ ((int, int));
 
 /* Cancel hourglass from protect_unwind.
    ARG is not used.  */
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
 static Lisp_Object
 cancel_hourglass_unwind (arg)
      Lisp_Object arg;
@@ -1891,7 +1891,7 @@ command_loop_1 ()
          /* Here for a command that isn't executed directly */
 
           {
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
             int scount = SPECPDL_INDEX ();
 
             if (display_hourglass_p
@@ -1907,7 +1907,7 @@ command_loop_1 ()
               Fundo_boundary ();
             Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
          /* Do not check display_hourglass_p here, because
             Fcommand_execute could change it, but we should cancel
             hourglass cursor anyway.
@@ -10273,7 +10273,7 @@ will read just one key sequence.  */)
       this_single_command_key_start = 0;
     }
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -10285,7 +10285,7 @@ will read just one key sequence.  */)
 #if 0  /* The following is fine for code reading a key sequence and
          then proceeding with a lenghty computation, but it's not good
          for code reading keys in a loop, like an input method.  */
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     start_hourglass ();
 #endif
@@ -10333,7 +10333,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
       this_single_command_key_start = 0;
     }
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -10342,7 +10342,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     start_hourglass ();
 #endif
@@ -10465,7 +10465,7 @@ give to the command you invoke, if it asks for an argument.  */)
   Lisp_Object saved_keys, saved_last_point_position_buffer;
   Lisp_Object bindings, value;
   struct gcpro gcpro1, gcpro2, gcpro3;
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   /* The call to Fcompleting_read wil start and cancel the hourglass,
      but if the hourglass was already scheduled, this means that no
      hourglass will be shown for the actual M-x command itself.
@@ -10505,7 +10505,7 @@ give to the command you invoke, if it asks for an argument.  */)
                               Qt, Qnil, Qextended_command_history, Qnil,
                               Qnil);
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (hstarted) start_hourglass ();
 #endif
 
index 86dd095..724de3f 100644 (file)
@@ -497,7 +497,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   if (EQ (Vminibuffer_completing_file_name, Qlambda))
     Vminibuffer_completing_file_name = Qnil;
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
index d88e86d..ed5decd 100644 (file)
@@ -154,6 +154,11 @@ Lisp_Object Vx_no_window_manager;
 
 int display_hourglass_p;
 
+/* If non-zero, a w32 timer that, when it expires, displays an
+   hourglass cursor on all frames.  */
+static unsigned hourglass_timer = 0;
+static HWND hourglass_hwnd = NULL;
+
 /* The background and shape of the mouse pointer, and shape when not
    over text or in the modeline.  */
 
@@ -304,6 +309,7 @@ unsigned int msh_mousewheel = 0;
 #define MOUSE_BUTTON_ID        1
 #define MOUSE_MOVE_ID  2
 #define MENU_FREE_ID 3
+#define HOURGLASS_ID 4
 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
    is received.  */
 #define MENU_FREE_DELAY 1000
@@ -335,6 +341,11 @@ static HWND w32_visible_system_caret_hwnd;
 extern HMENU current_popup_menu;
 static int menubar_in_use = 0;
 
+/* Function prototypes for hourglass support.  */
+static void show_hourglass P_ ((struct frame *));
+static void hide_hourglass P_ ((void));
+
+
 \f
 /* Error if we are not connected to MS-Windows.  */
 void
@@ -423,8 +434,6 @@ x_window_to_frame (dpyinfo, wdesc)
       f = XFRAME (frame);
       if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
        continue;
-      if (f->output_data.w32->hourglass_window == wdesc)
-        return f;
 
       if (FRAME_W32_WINDOW (f) == wdesc)
         return f;
@@ -3525,6 +3534,12 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
               menubar_in_use = 0;
            }
        }
+      else if (wParam == hourglass_timer)
+       {
+         KillTimer (hwnd, hourglass_timer);
+         hourglass_timer = 0;
+         show_hourglass (x_window_to_frame (dpyinfo, hwnd));
+       }
       return 0;
 
     case WM_NCACTIVATE:
@@ -3590,6 +3605,11 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       */
       if (f && menubar_in_use && current_popup_menu == NULL)
        menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
+
+      /* If hourglass cursor should be displayed, display it now.  */
+      if (f && f->output_data.w32->hourglass_p)
+       SetCursor (f->output_data.w32->hourglass_cursor);
+
       goto dflt;
 
     case WM_MENUSELECT:
@@ -3858,15 +3878,27 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
 
     case WM_SETCURSOR:
       if (LOWORD (lParam) == HTCLIENT)
-       return 0;
-
+       {
+         f = x_window_to_frame (dpyinfo, hwnd);
+         if (f->output_data.w32->hourglass_p && !menubar_in_use
+             && !current_popup_menu)
+           SetCursor (f->output_data.w32->hourglass_cursor);
+         else
+           SetCursor (f->output_data.w32->current_cursor);
+         return 0;
+       }
       goto dflt;
 
     case WM_EMACS_SETCURSOR:
       {
        Cursor cursor = (Cursor) wParam;
-       if (cursor)
-         SetCursor (cursor);
+       f = x_window_to_frame (dpyinfo, hwnd);
+       if (f && cursor)
+         {
+           f->output_data.w32->current_cursor = cursor;
+           if (!f->output_data.w32->hourglass_p)
+             SetCursor (cursor);
+         }
        return 0;
       }
 
@@ -4528,6 +4560,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
   f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
 
+  f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
+
   window_prompting = x_figure_window_size (f, parameters, 1);
 
   tem = w32_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
@@ -7216,11 +7250,6 @@ value.  */)
                                Busy cursor
  ***********************************************************************/
 
-/* If non-null, an asynchronous timer that, when it expires, displays
-   an hourglass cursor on all frames.  */
-
-static struct atimer *hourglass_atimer;
-
 /* Non-zero means an hourglass cursor is currently shown.  */
 
 static int hourglass_shown_p;
@@ -7234,20 +7263,22 @@ static Lisp_Object Vhourglass_delay;
 
 #define DEFAULT_HOURGLASS_DELAY 1
 
-/* Function prototypes.  */
-
-static void show_hourglass P_ ((struct atimer *));
-static void hide_hourglass P_ ((void));
+/* Return non-zero if houglass timer has been started or hourglass is shown.  */
 
+int
+hourglass_started ()
+{
+  return hourglass_shown_p || hourglass_timer;
+}
 
 /* Cancel a currently active hourglass timer, and start a new one.  */
 
 void
 start_hourglass ()
 {
-#if 0 /* TODO: cursor shape changes.  */
-  EMACS_TIME delay;
-  int secs, usecs = 0;
+  DWORD delay;
+  int secs, msecs = 0;
+  struct frame * f = SELECTED_FRAME ();
 
   cancel_hourglass ();
 
@@ -7260,15 +7291,14 @@ start_hourglass ()
       Lisp_Object tem;
       tem = Ftruncate (Vhourglass_delay, Qnil);
       secs = XFASTINT (tem);
-      usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
+      msecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000;
     }
   else
     secs = DEFAULT_HOURGLASS_DELAY;
 
-  EMACS_SET_SECS_USECS (delay, secs, usecs);
-  hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
-                                  show_hourglass, NULL);
-#endif
+  delay = secs * 1000 + msecs;
+  hourglass_hwnd = FRAME_W32_WINDOW (f);
+  hourglass_timer = SetTimer (hourglass_hwnd, HOURGLASS_ID, delay, NULL);
 }
 
 
@@ -7278,10 +7308,10 @@ start_hourglass ()
 void
 cancel_hourglass ()
 {
-  if (hourglass_atimer)
+  if (hourglass_timer)
     {
-      cancel_atimer (hourglass_atimer);
-      hourglass_atimer = NULL;
+      KillTimer (hourglass_hwnd, hourglass_timer);
+      hourglass_timer = 0;
     }
 
   if (hourglass_shown_p)
@@ -7289,62 +7319,22 @@ cancel_hourglass ()
 }
 
 
-/* Timer function of hourglass_atimer.  TIMER is equal to
-   hourglass_atimer.
+/* Timer function of hourglass_timer.
 
-   Display an hourglass cursor on all frames by mapping the frames'
-   hourglass_window.  Set the hourglass_p flag in the frames'
-   output_data.x structure to indicate that an hourglass cursor is
-   shown on the frames.  */
+   Display an hourglass cursor.  Set the hourglass_p flag in display info
+   to indicate that an hourglass cursor is shown.  */
 
 static void
-show_hourglass (timer)
-     struct atimer *timer;
+show_hourglass (f)
+     struct frame *f;
 {
-#if 0  /* TODO: cursor shape changes.  */
-  /* The timer implementation will cancel this timer automatically
-     after this function has run.  Set hourglass_atimer to null
-     so that we know the timer doesn't have to be canceled.  */
-  hourglass_atimer = NULL;
-
   if (!hourglass_shown_p)
     {
-      Lisp_Object rest, frame;
-
-      BLOCK_INPUT;
-
-      FOR_EACH_FRAME (rest, frame)
-       if (FRAME_W32_P (XFRAME (frame)))
-         {
-           struct frame *f = XFRAME (frame);
-
-           f->output_data.w32->hourglass_p = 1;
-
-           if (!f->output_data.w32->hourglass_window)
-             {
-               unsigned long mask = CWCursor;
-               XSetWindowAttributes attrs;
-
-               attrs.cursor = f->output_data.w32->hourglass_cursor;
-
-               f->output_data.w32->hourglass_window
-                 = XCreateWindow (FRAME_X_DISPLAY (f),
-                                  FRAME_OUTER_WINDOW (f),
-                                  0, 0, 32000, 32000, 0, 0,
-                                  InputOnly,
-                                  CopyFromParent,
-                                  mask, &attrs);
-             }
-
-           XMapRaised (FRAME_X_DISPLAY (f),
-                       f->output_data.w32->hourglass_window);
-           XFlush (FRAME_X_DISPLAY (f));
-         }
-
+      f->output_data.w32->hourglass_p = 1;
+      if (!menubar_in_use && !current_popup_menu)
+       SetCursor (f->output_data.w32->hourglass_cursor);
       hourglass_shown_p = 1;
-      UNBLOCK_INPUT;
     }
-#endif
 }
 
 
@@ -7353,33 +7343,15 @@ show_hourglass (timer)
 static void
 hide_hourglass ()
 {
-#if 0 /* TODO: cursor shape changes.  */
   if (hourglass_shown_p)
     {
-      Lisp_Object rest, frame;
-
-      BLOCK_INPUT;
-      FOR_EACH_FRAME (rest, frame)
-       {
-         struct frame *f = XFRAME (frame);
-
-         if (FRAME_W32_P (f)
-             /* Watch out for newly created frames.  */
-             && f->output_data.x->hourglass_window)
-           {
-             XUnmapWindow (FRAME_X_DISPLAY (f),
-                           f->output_data.x->hourglass_window);
-             /* Sync here because XTread_socket looks at the
-                hourglass_p flag that is reset to zero below.  */
-             XSync (FRAME_X_DISPLAY (f), False);
-             f->output_data.x->hourglass_p = 0;
-           }
-       }
+      struct frame *f = x_window_to_frame (&one_w32_display_info,
+                                          hourglass_hwnd);
 
+      f->output_data.w32->hourglass_p = 0;
+      SetCursor (f->output_data.w32->current_cursor);
       hourglass_shown_p = 0;
-      UNBLOCK_INPUT;
     }
-#endif
 }
 
 
@@ -9323,7 +9295,8 @@ versions of Windows) characters.  */);
   check_window_system_func = check_w32;
 
 
-  hourglass_atimer = NULL;
+  hourglass_timer = 0;
+  hourglass_hwnd = NULL;
   hourglass_shown_p = 0;
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
index d6b20bc..5af3eac 100644 (file)
@@ -361,13 +361,12 @@ struct w32_output
   Cursor hourglass_cursor;
   Cursor horizontal_drag_cursor;
 
-  /* Window whose cursor is hourglass_cursor.  This window is
-     temporarily mapped to display an hourglass cursor.  */
-  Window hourglass_window;
-
   /* Non-zero means hourglass cursor is currently displayed.  */
   unsigned hourglass_p : 1;
 
+  /* Non-hourglass cursor that is currently active.  */
+  Cursor current_cursor;
+
   /* Flag to set when the window needs to be completely repainted.  */
   int needs_exposure;