comparison src/w32fns.c @ 93075:66248fc5b523

* 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.
author Jason Rumney <jasonr@gnu.org>
date Wed, 19 Mar 2008 17:04:14 +0000
parents 23d6a73f69ad
children a461c5c16bd5
comparison
equal deleted inserted replaced
93074:620496d91e55 93075:66248fc5b523
152 152
153 /* Non-zero means we're allowed to display a hourglass pointer. */ 153 /* Non-zero means we're allowed to display a hourglass pointer. */
154 154
155 int display_hourglass_p; 155 int display_hourglass_p;
156 156
157 /* If non-zero, a w32 timer that, when it expires, displays an
158 hourglass cursor on all frames. */
159 static unsigned hourglass_timer = 0;
160 static HWND hourglass_hwnd = NULL;
161
157 /* The background and shape of the mouse pointer, and shape when not 162 /* The background and shape of the mouse pointer, and shape when not
158 over text or in the modeline. */ 163 over text or in the modeline. */
159 164
160 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape; 165 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
161 Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape; 166 Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
302 307
303 /* Timers */ 308 /* Timers */
304 #define MOUSE_BUTTON_ID 1 309 #define MOUSE_BUTTON_ID 1
305 #define MOUSE_MOVE_ID 2 310 #define MOUSE_MOVE_ID 2
306 #define MENU_FREE_ID 3 311 #define MENU_FREE_ID 3
312 #define HOURGLASS_ID 4
307 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP 313 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
308 is received. */ 314 is received. */
309 #define MENU_FREE_DELAY 1000 315 #define MENU_FREE_DELAY 1000
310 static unsigned menu_free_timer = 0; 316 static unsigned menu_free_timer = 0;
311 317
332 static HWND w32_visible_system_caret_hwnd; 338 static HWND w32_visible_system_caret_hwnd;
333 339
334 /* From w32menu.c */ 340 /* From w32menu.c */
335 extern HMENU current_popup_menu; 341 extern HMENU current_popup_menu;
336 static int menubar_in_use = 0; 342 static int menubar_in_use = 0;
343
344 /* Function prototypes for hourglass support. */
345 static void show_hourglass P_ ((struct frame *));
346 static void hide_hourglass P_ ((void));
347
337 348
338 349
339 /* Error if we are not connected to MS-Windows. */ 350 /* Error if we are not connected to MS-Windows. */
340 void 351 void
341 check_w32 () 352 check_w32 ()
421 if (!FRAMEP (frame)) 432 if (!FRAMEP (frame))
422 continue; 433 continue;
423 f = XFRAME (frame); 434 f = XFRAME (frame);
424 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo) 435 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
425 continue; 436 continue;
426 if (f->output_data.w32->hourglass_window == wdesc)
427 return f;
428 437
429 if (FRAME_W32_WINDOW (f) == wdesc) 438 if (FRAME_W32_WINDOW (f) == wdesc)
430 return f; 439 return f;
431 } 440 }
432 return 0; 441 return 0;
3523 w32_free_menu_strings (hwnd); 3532 w32_free_menu_strings (hwnd);
3524 f->output_data.w32->menubar_active = 0; 3533 f->output_data.w32->menubar_active = 0;
3525 menubar_in_use = 0; 3534 menubar_in_use = 0;
3526 } 3535 }
3527 } 3536 }
3537 else if (wParam == hourglass_timer)
3538 {
3539 KillTimer (hwnd, hourglass_timer);
3540 hourglass_timer = 0;
3541 show_hourglass (x_window_to_frame (dpyinfo, hwnd));
3542 }
3528 return 0; 3543 return 0;
3529 3544
3530 case WM_NCACTIVATE: 3545 case WM_NCACTIVATE:
3531 /* Windows doesn't send us focus messages when putting up and 3546 /* Windows doesn't send us focus messages when putting up and
3532 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95. 3547 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
3588 Don't do this if a popup menu is active, since it is only 3603 Don't do this if a popup menu is active, since it is only
3589 menubar menus that require cleaning up in this way. 3604 menubar menus that require cleaning up in this way.
3590 */ 3605 */
3591 if (f && menubar_in_use && current_popup_menu == NULL) 3606 if (f && menubar_in_use && current_popup_menu == NULL)
3592 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL); 3607 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
3608
3609 /* If hourglass cursor should be displayed, display it now. */
3610 if (f && f->output_data.w32->hourglass_p)
3611 SetCursor (f->output_data.w32->hourglass_cursor);
3612
3593 goto dflt; 3613 goto dflt;
3594 3614
3595 case WM_MENUSELECT: 3615 case WM_MENUSELECT:
3596 /* Direct handling of help_echo in menus. Should be safe now 3616 /* Direct handling of help_echo in menus. Should be safe now
3597 that we generate the help_echo by placing a help event in the 3617 that we generate the help_echo by placing a help event in the
3856 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767; 3876 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
3857 return 0; 3877 return 0;
3858 3878
3859 case WM_SETCURSOR: 3879 case WM_SETCURSOR:
3860 if (LOWORD (lParam) == HTCLIENT) 3880 if (LOWORD (lParam) == HTCLIENT)
3861 return 0; 3881 {
3862 3882 f = x_window_to_frame (dpyinfo, hwnd);
3883 if (f->output_data.w32->hourglass_p && !menubar_in_use
3884 && !current_popup_menu)
3885 SetCursor (f->output_data.w32->hourglass_cursor);
3886 else
3887 SetCursor (f->output_data.w32->current_cursor);
3888 return 0;
3889 }
3863 goto dflt; 3890 goto dflt;
3864 3891
3865 case WM_EMACS_SETCURSOR: 3892 case WM_EMACS_SETCURSOR:
3866 { 3893 {
3867 Cursor cursor = (Cursor) wParam; 3894 Cursor cursor = (Cursor) wParam;
3868 if (cursor) 3895 f = x_window_to_frame (dpyinfo, hwnd);
3869 SetCursor (cursor); 3896 if (f && cursor)
3897 {
3898 f->output_data.w32->current_cursor = cursor;
3899 if (!f->output_data.w32->hourglass_p)
3900 SetCursor (cursor);
3901 }
3870 return 0; 3902 return 0;
3871 } 3903 }
3872 3904
3873 case WM_EMACS_CREATESCROLLBAR: 3905 case WM_EMACS_CREATESCROLLBAR:
3874 return (LRESULT) w32_createscrollbar ((struct frame *) wParam, 3906 return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
4525 f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW); 4557 f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
4526 f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW); 4558 f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
4527 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND); 4559 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
4528 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT); 4560 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
4529 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE); 4561 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
4562
4563 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
4530 4564
4531 window_prompting = x_figure_window_size (f, parameters, 1); 4565 window_prompting = x_figure_window_size (f, parameters, 1);
4532 4566
4533 tem = w32_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); 4567 tem = w32_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
4534 f->no_split = minibuffer_only || EQ (tem, Qt); 4568 f->no_split = minibuffer_only || EQ (tem, Qt);
7214 7248
7215 /*********************************************************************** 7249 /***********************************************************************
7216 Busy cursor 7250 Busy cursor
7217 ***********************************************************************/ 7251 ***********************************************************************/
7218 7252
7219 /* If non-null, an asynchronous timer that, when it expires, displays
7220 an hourglass cursor on all frames. */
7221
7222 static struct atimer *hourglass_atimer;
7223
7224 /* Non-zero means an hourglass cursor is currently shown. */ 7253 /* Non-zero means an hourglass cursor is currently shown. */
7225 7254
7226 static int hourglass_shown_p; 7255 static int hourglass_shown_p;
7227 7256
7228 /* Number of seconds to wait before displaying an hourglass cursor. */ 7257 /* Number of seconds to wait before displaying an hourglass cursor. */
7232 /* Default number of seconds to wait before displaying an hourglass 7261 /* Default number of seconds to wait before displaying an hourglass
7233 cursor. */ 7262 cursor. */
7234 7263
7235 #define DEFAULT_HOURGLASS_DELAY 1 7264 #define DEFAULT_HOURGLASS_DELAY 1
7236 7265
7237 /* Function prototypes. */ 7266 /* Return non-zero if houglass timer has been started or hourglass is shown. */
7238 7267
7239 static void show_hourglass P_ ((struct atimer *)); 7268 int
7240 static void hide_hourglass P_ ((void)); 7269 hourglass_started ()
7241 7270 {
7271 return hourglass_shown_p || hourglass_timer;
7272 }
7242 7273
7243 /* Cancel a currently active hourglass timer, and start a new one. */ 7274 /* Cancel a currently active hourglass timer, and start a new one. */
7244 7275
7245 void 7276 void
7246 start_hourglass () 7277 start_hourglass ()
7247 { 7278 {
7248 #if 0 /* TODO: cursor shape changes. */ 7279 DWORD delay;
7249 EMACS_TIME delay; 7280 int secs, msecs = 0;
7250 int secs, usecs = 0; 7281 struct frame * f = SELECTED_FRAME ();
7251 7282
7252 cancel_hourglass (); 7283 cancel_hourglass ();
7253 7284
7254 if (INTEGERP (Vhourglass_delay) 7285 if (INTEGERP (Vhourglass_delay)
7255 && XINT (Vhourglass_delay) > 0) 7286 && XINT (Vhourglass_delay) > 0)
7258 && XFLOAT_DATA (Vhourglass_delay) > 0) 7289 && XFLOAT_DATA (Vhourglass_delay) > 0)
7259 { 7290 {
7260 Lisp_Object tem; 7291 Lisp_Object tem;
7261 tem = Ftruncate (Vhourglass_delay, Qnil); 7292 tem = Ftruncate (Vhourglass_delay, Qnil);
7262 secs = XFASTINT (tem); 7293 secs = XFASTINT (tem);
7263 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000; 7294 msecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000;
7264 } 7295 }
7265 else 7296 else
7266 secs = DEFAULT_HOURGLASS_DELAY; 7297 secs = DEFAULT_HOURGLASS_DELAY;
7267 7298
7268 EMACS_SET_SECS_USECS (delay, secs, usecs); 7299 delay = secs * 1000 + msecs;
7269 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, 7300 hourglass_hwnd = FRAME_W32_WINDOW (f);
7270 show_hourglass, NULL); 7301 hourglass_timer = SetTimer (hourglass_hwnd, HOURGLASS_ID, delay, NULL);
7271 #endif
7272 } 7302 }
7273 7303
7274 7304
7275 /* Cancel the hourglass cursor timer if active, hide an hourglass 7305 /* Cancel the hourglass cursor timer if active, hide an hourglass
7276 cursor if shown. */ 7306 cursor if shown. */
7277 7307
7278 void 7308 void
7279 cancel_hourglass () 7309 cancel_hourglass ()
7280 { 7310 {
7281 if (hourglass_atimer) 7311 if (hourglass_timer)
7282 { 7312 {
7283 cancel_atimer (hourglass_atimer); 7313 KillTimer (hourglass_hwnd, hourglass_timer);
7284 hourglass_atimer = NULL; 7314 hourglass_timer = 0;
7285 } 7315 }
7286 7316
7287 if (hourglass_shown_p) 7317 if (hourglass_shown_p)
7288 hide_hourglass (); 7318 hide_hourglass ();
7289 } 7319 }
7290 7320
7291 7321
7292 /* Timer function of hourglass_atimer. TIMER is equal to 7322 /* Timer function of hourglass_timer.
7293 hourglass_atimer. 7323
7294 7324 Display an hourglass cursor. Set the hourglass_p flag in display info
7295 Display an hourglass cursor on all frames by mapping the frames' 7325 to indicate that an hourglass cursor is shown. */
7296 hourglass_window. Set the hourglass_p flag in the frames'
7297 output_data.x structure to indicate that an hourglass cursor is
7298 shown on the frames. */
7299 7326
7300 static void 7327 static void
7301 show_hourglass (timer) 7328 show_hourglass (f)
7302 struct atimer *timer; 7329 struct frame *f;
7303 { 7330 {
7304 #if 0 /* TODO: cursor shape changes. */
7305 /* The timer implementation will cancel this timer automatically
7306 after this function has run. Set hourglass_atimer to null
7307 so that we know the timer doesn't have to be canceled. */
7308 hourglass_atimer = NULL;
7309
7310 if (!hourglass_shown_p) 7331 if (!hourglass_shown_p)
7311 { 7332 {
7312 Lisp_Object rest, frame; 7333 f->output_data.w32->hourglass_p = 1;
7313 7334 if (!menubar_in_use && !current_popup_menu)
7314 BLOCK_INPUT; 7335 SetCursor (f->output_data.w32->hourglass_cursor);
7315
7316 FOR_EACH_FRAME (rest, frame)
7317 if (FRAME_W32_P (XFRAME (frame)))
7318 {
7319 struct frame *f = XFRAME (frame);
7320
7321 f->output_data.w32->hourglass_p = 1;
7322
7323 if (!f->output_data.w32->hourglass_window)
7324 {
7325 unsigned long mask = CWCursor;
7326 XSetWindowAttributes attrs;
7327
7328 attrs.cursor = f->output_data.w32->hourglass_cursor;
7329
7330 f->output_data.w32->hourglass_window
7331 = XCreateWindow (FRAME_X_DISPLAY (f),
7332 FRAME_OUTER_WINDOW (f),
7333 0, 0, 32000, 32000, 0, 0,
7334 InputOnly,
7335 CopyFromParent,
7336 mask, &attrs);
7337 }
7338
7339 XMapRaised (FRAME_X_DISPLAY (f),
7340 f->output_data.w32->hourglass_window);
7341 XFlush (FRAME_X_DISPLAY (f));
7342 }
7343
7344 hourglass_shown_p = 1; 7336 hourglass_shown_p = 1;
7345 UNBLOCK_INPUT; 7337 }
7346 }
7347 #endif
7348 } 7338 }
7349 7339
7350 7340
7351 /* Hide the hourglass cursor on all frames, if it is currently shown. */ 7341 /* Hide the hourglass cursor on all frames, if it is currently shown. */
7352 7342
7353 static void 7343 static void
7354 hide_hourglass () 7344 hide_hourglass ()
7355 { 7345 {
7356 #if 0 /* TODO: cursor shape changes. */
7357 if (hourglass_shown_p) 7346 if (hourglass_shown_p)
7358 { 7347 {
7359 Lisp_Object rest, frame; 7348 struct frame *f = x_window_to_frame (&one_w32_display_info,
7360 7349 hourglass_hwnd);
7361 BLOCK_INPUT; 7350
7362 FOR_EACH_FRAME (rest, frame) 7351 f->output_data.w32->hourglass_p = 0;
7363 { 7352 SetCursor (f->output_data.w32->current_cursor);
7364 struct frame *f = XFRAME (frame);
7365
7366 if (FRAME_W32_P (f)
7367 /* Watch out for newly created frames. */
7368 && f->output_data.x->hourglass_window)
7369 {
7370 XUnmapWindow (FRAME_X_DISPLAY (f),
7371 f->output_data.x->hourglass_window);
7372 /* Sync here because XTread_socket looks at the
7373 hourglass_p flag that is reset to zero below. */
7374 XSync (FRAME_X_DISPLAY (f), False);
7375 f->output_data.x->hourglass_p = 0;
7376 }
7377 }
7378
7379 hourglass_shown_p = 0; 7353 hourglass_shown_p = 0;
7380 UNBLOCK_INPUT; 7354 }
7381 }
7382 #endif
7383 } 7355 }
7384 7356
7385 7357
7386 7358
7387 /*********************************************************************** 7359 /***********************************************************************
9321 set_frame_fontset_func = x_set_font; 9293 set_frame_fontset_func = x_set_font;
9322 get_font_repertory_func = x_get_font_repertory; 9294 get_font_repertory_func = x_get_font_repertory;
9323 check_window_system_func = check_w32; 9295 check_window_system_func = check_w32;
9324 9296
9325 9297
9326 hourglass_atimer = NULL; 9298 hourglass_timer = 0;
9299 hourglass_hwnd = NULL;
9327 hourglass_shown_p = 0; 9300 hourglass_shown_p = 0;
9328 defsubr (&Sx_show_tip); 9301 defsubr (&Sx_show_tip);
9329 defsubr (&Sx_hide_tip); 9302 defsubr (&Sx_hide_tip);
9330 tip_timer = Qnil; 9303 tip_timer = Qnil;
9331 staticpro (&tip_timer); 9304 staticpro (&tip_timer);