comparison src/msdos.c @ 30341:2ad638704621

(IT_note_mode_line_highlight, IT_note_mouse_highlight): Record the object that generated the help echo and the position of that object in help_echo_object and help_echo_pos. Record that some glyphs in a row are displayed in mouse-face. (IT_update_begin): Don't clear mouse highlight unless one of the enabled glyph rows is marked as being displayed in mouse-face. (dos_rawgetc): Generate 2 events for HELP_EVENT. Pass the object and position recorded in help_echo_object and help_echo_pos to the event queue. (IT_menu_display): Accept a new argument PN: the pane number of the current menu pane. Record the pane number and the item number of the item which has associated help string. (XMenuActivate): Update the prototype for help_callback in function declaration. Call IT_menu_display with the current menu pane number as an additional argument. Call help_callback with two additional arguments: the pane number and the item number of the menu item associated with the help text. (help_echo_object, help_echo_pos): New variables. (syms_of_msdos): Initialize them and staticpro help_echo_object. (help_echo_window): New variable. (syms_of_msdos): Initialize and staticpro it. (IT_note_mode_line_highlight): Set help_echo_window. (IT_note_mouse_highlight): Ditto. (dos_rawgetc): Store help_echo_window in the second event produced for HELP_EVENTs.
author Eli Zaretskii <eliz@gnu.org>
date Thu, 20 Jul 2000 11:06:17 +0000
parents f39367e12c14
children ace34a073127
comparison
equal deleted inserted replaced
30340:be29e15ece0e 30341:2ad638704621
1110 ************************************************************************/ 1110 ************************************************************************/
1111 1111
1112 /* This is used for debugging, to turn off note_mouse_highlight. */ 1112 /* This is used for debugging, to turn off note_mouse_highlight. */
1113 int disable_mouse_highlight; 1113 int disable_mouse_highlight;
1114 1114
1115 /* If a string, dos_rawgetc generates an event to display that string. 1115 /* If non-nil, dos_rawgetc generates an event to display that string.
1116 (The display is done in keyboard.c:read_char.) */ 1116 (The display is done in keyboard.c:read_char, by calling
1117 show_help_echo.) */
1117 static Lisp_Object help_echo; 1118 static Lisp_Object help_echo;
1118 static Lisp_Object previous_help_echo; /* a helper temporary variable */ 1119 static Lisp_Object previous_help_echo; /* a helper temporary variable */
1120
1121 /* These record the window, the object and the position where the help
1122 echo string was generated. */
1123 static Lisp_Object help_echo_window;
1124 static Lisp_Object help_echo_object;
1125 static int help_echo_pos;
1119 1126
1120 static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ 1127 static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */
1121 1128
1122 /* Set the mouse pointer shape according to whether it is in the 1129 /* Set the mouse pointer shape according to whether it is in the
1123 area where the mouse highlight is in effect. */ 1130 area where the mouse highlight is in effect. */
1184 else 1191 else
1185 end_hpos = row->used[TEXT_AREA]; 1192 end_hpos = row->used[TEXT_AREA];
1186 1193
1187 if (end_hpos <= start_hpos) 1194 if (end_hpos <= start_hpos)
1188 continue; 1195 continue;
1196 /* Record that some glyphs of this row are displayed in
1197 mouse-face. */
1198 row->mouse_face_p = hl > 0;
1189 if (hl > 0) 1199 if (hl > 0)
1190 { 1200 {
1191 int vpos = row->y + WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w); 1201 int vpos = row->y + WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w);
1192 int kstart = start_hpos + WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w); 1202 int kstart = start_hpos + WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w);
1193 int nglyphs = end_hpos - start_hpos; 1203 int nglyphs = end_hpos - start_hpos;
1374 arrange for the help to be displayed. This is done by 1384 arrange for the help to be displayed. This is done by
1375 setting the global variable help_echo to the help string. */ 1385 setting the global variable help_echo to the help string. */
1376 help = Fget_text_property (make_number (glyph->charpos), 1386 help = Fget_text_property (make_number (glyph->charpos),
1377 Qhelp_echo, glyph->object); 1387 Qhelp_echo, glyph->object);
1378 if (!NILP (help)) 1388 if (!NILP (help))
1379 help_echo = help; 1389 {
1390 help_echo = help;
1391 XSETWINDOW (help_echo_window, w);
1392 help_echo_object = glyph->object;
1393 help_echo_pos = glyph->charpos;
1394 }
1380 } 1395 }
1381 } 1396 }
1382 } 1397 }
1383 1398
1384 /* Take proper action when the mouse has moved to position X, Y on 1399 /* Take proper action when the mouse has moved to position X, Y on
1624 /* Check overlays first. */ 1639 /* Check overlays first. */
1625 help = Qnil; 1640 help = Qnil;
1626 for (i = 0; i < noverlays && NILP (help); ++i) 1641 for (i = 0; i < noverlays && NILP (help); ++i)
1627 help = Foverlay_get (overlay_vec[i], Qhelp_echo); 1642 help = Foverlay_get (overlay_vec[i], Qhelp_echo);
1628 1643
1644 if (!NILP (help))
1645 {
1646 help_echo = help;
1647 help_echo_window = window;
1648 help_echo_object = w->buffer;
1649 help_echo_pos = pos;
1650 }
1629 /* Try text properties. */ 1651 /* Try text properties. */
1630 if (NILP (help) 1652 else if (NILP (help)
1631 && ((STRINGP (glyph->object) 1653 && ((STRINGP (glyph->object)
1632 && glyph->charpos >= 0 1654 && glyph->charpos >= 0
1633 && glyph->charpos < XSTRING (glyph->object)->size) 1655 && glyph->charpos < XSTRING (glyph->object)->size)
1634 || (BUFFERP (glyph->object) 1656 || (BUFFERP (glyph->object)
1635 && glyph->charpos >= BEGV 1657 && glyph->charpos >= BEGV
1636 && glyph->charpos < ZV))) 1658 && glyph->charpos < ZV)))
1637 help = Fget_text_property (make_number (glyph->charpos), 1659 {
1638 Qhelp_echo, glyph->object); 1660 help = Fget_text_property (make_number (glyph->charpos),
1639 1661 Qhelp_echo, glyph->object);
1640 if (!NILP (help)) 1662 if (!NILP (help))
1641 help_echo = help; 1663 {
1664 help_echo = help;
1665 help_echo_window = window;
1666 help_echo_object = glyph->object;
1667 help_echo_pos = glyph->charpos;
1668 }
1669 }
1642 } 1670 }
1643 1671
1644 BEGV = obegv; 1672 BEGV = obegv;
1645 ZV = ozv; 1673 ZV = ozv;
1646 current_buffer = obuf; 1674 current_buffer = obuf;
1853 if (FRAME_GARBAGED_P (f)) 1881 if (FRAME_GARBAGED_P (f))
1854 display_info->mouse_face_window = Qnil; 1882 display_info->mouse_face_window = Qnil;
1855 1883
1856 /* Can we tell that this update does not affect the window 1884 /* Can we tell that this update does not affect the window
1857 where the mouse highlight is? If so, no need to turn off. 1885 where the mouse highlight is? If so, no need to turn off.
1858 Likewise, don't do anything if the frame is garbaged; 1886 Likewise, don't do anything if none of the enabled rows
1859 in that case, the frame's current matrix that we would use 1887 contains glyphs highlighted in mouse face. */
1860 is all wrong, and we will redisplay that line anyway. */
1861 if (!NILP (display_info->mouse_face_window) 1888 if (!NILP (display_info->mouse_face_window)
1862 && WINDOWP (display_info->mouse_face_window)) 1889 && WINDOWP (display_info->mouse_face_window))
1863 { 1890 {
1864 struct window *w = XWINDOW (display_info->mouse_face_window); 1891 struct window *w = XWINDOW (display_info->mouse_face_window);
1865 int i; 1892 int i;
1870 if (NILP (w->buffer)) 1897 if (NILP (w->buffer))
1871 display_info->mouse_face_window = Qnil; 1898 display_info->mouse_face_window = Qnil;
1872 else 1899 else
1873 { 1900 {
1874 for (i = 0; i < w->desired_matrix->nrows; ++i) 1901 for (i = 0; i < w->desired_matrix->nrows; ++i)
1875 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i)) 1902 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i)
1903 && MATRIX_ROW (w->current_matrix, i)->mouse_face_p)
1876 break; 1904 break;
1877 } 1905 }
1878 1906
1879 if (NILP (w->buffer) || i < w->desired_matrix->nrows) 1907 if (NILP (w->buffer) || i < w->desired_matrix->nrows)
1880 clear_mouse_face (display_info); 1908 clear_mouse_face (display_info);
3233 /* If the mouse moved from the spot of its last sighting, we 3261 /* If the mouse moved from the spot of its last sighting, we
3234 might need to update mouse highlight. */ 3262 might need to update mouse highlight. */
3235 if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y) 3263 if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y)
3236 { 3264 {
3237 previous_help_echo = help_echo; 3265 previous_help_echo = help_echo;
3238 help_echo = Qnil; 3266 help_echo = help_echo_object = help_echo_window = Qnil;
3267 help_echo_pos = -1;
3239 IT_note_mouse_highlight (SELECTED_FRAME(), 3268 IT_note_mouse_highlight (SELECTED_FRAME(),
3240 mouse_last_x, mouse_last_y); 3269 mouse_last_x, mouse_last_y);
3241 /* If the contents of the global variable help_echo has 3270 /* If the contents of the global variable help_echo has
3242 changed, generate a HELP_EVENT. */ 3271 changed, generate a HELP_EVENT. */
3243 if (!NILP (help_echo) || !NILP (previous_help_echo)) 3272 if (!NILP (help_echo) || !NILP (previous_help_echo))
3244 { 3273 {
3274 /* HELP_EVENT takes 2 events in the event loop. */
3245 event.kind = HELP_EVENT; 3275 event.kind = HELP_EVENT;
3246 event.frame_or_window = selected_frame; 3276 event.frame_or_window = selected_frame;
3277 event.arg = help_echo_object;
3278 event.x = make_number (help_echo_pos);
3279 event.timestamp = event_timestamp ();
3280 event.code = 0;
3281 kbd_buffer_store_event (&event);
3282 if (WINDOWP (help_echo_window))
3283 event.frame_or_window = help_echo_window;
3247 event.arg = help_echo; 3284 event.arg = help_echo;
3248 event.timestamp = event_timestamp (); 3285 event.code = 1;
3249 kbd_buffer_store_event (&event); 3286 kbd_buffer_store_event (&event);
3250 } 3287 }
3251 } 3288 }
3252 3289
3253 for (but = 0; but < NUM_MOUSE_BUTTONS; but++) 3290 for (but = 0; but < NUM_MOUSE_BUTTONS; but++)
3359 Actually, I don't know the meaning of all the parameters of the functions 3396 Actually, I don't know the meaning of all the parameters of the functions
3360 here -- I only know how they are called by xmenu.c. I could of course 3397 here -- I only know how they are called by xmenu.c. I could of course
3361 grab the nearest Xlib manual (down the hall, second-to-last door on the 3398 grab the nearest Xlib manual (down the hall, second-to-last door on the
3362 left), but I don't think it's worth the effort. */ 3399 left), but I don't think it's worth the effort. */
3363 3400
3401 /* These hold text of the current and the previous menu help messages. */
3364 static char *menu_help_message, *prev_menu_help_message; 3402 static char *menu_help_message, *prev_menu_help_message;
3403 /* Pane number and item number of the menu item which generated the
3404 last menu help message. */
3405 static int menu_help_paneno, menu_help_itemno;
3365 3406
3366 static XMenu * 3407 static XMenu *
3367 IT_menu_create () 3408 IT_menu_create ()
3368 { 3409 {
3369 XMenu *menu; 3410 XMenu *menu;
3443 } 3484 }
3444 3485
3445 /* Display MENU at (X,Y) using FACES. */ 3486 /* Display MENU at (X,Y) using FACES. */
3446 3487
3447 static void 3488 static void
3448 IT_menu_display (XMenu *menu, int y, int x, int *faces, int disp_help) 3489 IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
3449 { 3490 {
3450 int i, j, face, width; 3491 int i, j, face, width;
3451 struct glyph *text, *p; 3492 struct glyph *text, *p;
3452 char *q; 3493 char *q;
3453 int mx, my; 3494 int mx, my;
3469 IT_cursor_to (y + i, x); 3510 IT_cursor_to (y + i, x);
3470 enabled 3511 enabled
3471 = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); 3512 = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
3472 mousehere = (y + i == my && x <= mx && mx < x + width + 2); 3513 mousehere = (y + i == my && x <= mx && mx < x + width + 2);
3473 face = faces[enabled + mousehere * 2]; 3514 face = faces[enabled + mousehere * 2];
3515 /* The following if clause means that we display the menu help
3516 strings even if the menu item is currently disabled. */
3474 if (disp_help && enabled + mousehere * 2 >= 2) 3517 if (disp_help && enabled + mousehere * 2 >= 2)
3475 menu_help_message = menu->help_text[i]; 3518 {
3519 menu_help_message = menu->help_text[i];
3520 menu_help_paneno = pn - 1;
3521 menu_help_itemno = i;
3522 }
3476 p = text; 3523 p = text;
3477 SET_CHAR_GLYPH (*p, ' ', face, 0); 3524 SET_CHAR_GLYPH (*p, ' ', face, 0);
3478 p++; 3525 p++;
3479 for (j = 0, q = menu->text[i]; *q; j++) 3526 for (j = 0, q = menu->text[i]; *q; j++)
3480 { 3527 {
3615 /* Display menu, wait for user's response, and return that response. */ 3662 /* Display menu, wait for user's response, and return that response. */
3616 3663
3617 int 3664 int
3618 XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, 3665 XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
3619 int x0, int y0, unsigned ButtonMask, char **txt, 3666 int x0, int y0, unsigned ButtonMask, char **txt,
3620 void (*help_callback)(char *)) 3667 void (*help_callback)(char *, int, int))
3621 { 3668 {
3622 struct IT_menu_state *state; 3669 struct IT_menu_state *state;
3623 int statecount; 3670 int statecount;
3624 int x, y, i, b; 3671 int x, y, i, b;
3625 int screensize; 3672 int screensize;
3640 x0 = 1; 3687 x0 = 1;
3641 if (y0 <= 0) 3688 if (y0 <= 0)
3642 y0 = 1; 3689 y0 = 1;
3643 3690
3644 /* We will process all the mouse events directly, so we had 3691 /* We will process all the mouse events directly, so we had
3645 better prevented dos_rawgetc from stealing them from us. */ 3692 better prevent dos_rawgetc from stealing them from us. */
3646 mouse_preempted++; 3693 mouse_preempted++;
3647 3694
3648 state = alloca (menu->panecount * sizeof (struct IT_menu_state)); 3695 state = alloca (menu->panecount * sizeof (struct IT_menu_state));
3649 screensize = screen_size * 2; 3696 screensize = screen_size * 2;
3650 faces[0] 3697 faces[0]
3689 /* Turn off the cursor. Otherwise it shows through the menu 3736 /* Turn off the cursor. Otherwise it shows through the menu
3690 panes, which is ugly. */ 3737 panes, which is ugly. */
3691 IT_display_cursor (0); 3738 IT_display_cursor (0);
3692 3739
3693 /* Display the menu title. */ 3740 /* Display the menu title. */
3694 IT_menu_display (menu, y0 - 1, x0 - 1, title_faces, 0); 3741 IT_menu_display (menu, y0 - 1, x0 - 1, 1, title_faces, 0);
3695 if (buffers_num_deleted) 3742 if (buffers_num_deleted)
3696 menu->text[0][7] = ' '; 3743 menu->text[0][7] = ' ';
3697 if ((onepane = menu->count == 1 && menu->submenu[0])) 3744 if ((onepane = menu->count == 1 && menu->submenu[0]))
3698 { 3745 {
3699 menu->width = menu->submenu[0]->width; 3746 menu->width = menu->submenu[0]->width;
3748 if (i == statecount - 1 && state[i].menu->submenu[dy]) 3795 if (i == statecount - 1 && state[i].menu->submenu[dy])
3749 { 3796 {
3750 IT_menu_display (state[i].menu, 3797 IT_menu_display (state[i].menu,
3751 state[i].y, 3798 state[i].y,
3752 state[i].x, 3799 state[i].x,
3800 state[i].pane,
3753 faces, 1); 3801 faces, 1);
3754 state[statecount].menu = state[i].menu->submenu[dy]; 3802 state[statecount].menu = state[i].menu->submenu[dy];
3755 state[statecount].pane = state[i].menu->panenumber[dy]; 3803 state[statecount].pane = state[i].menu->panenumber[dy];
3756 mouse_off (); 3804 mouse_off ();
3757 ScreenRetrieve (state[statecount].screen_behind 3805 ScreenRetrieve (state[statecount].screen_behind
3764 } 3812 }
3765 } 3813 }
3766 IT_menu_display (state[statecount - 1].menu, 3814 IT_menu_display (state[statecount - 1].menu,
3767 state[statecount - 1].y, 3815 state[statecount - 1].y,
3768 state[statecount - 1].x, 3816 state[statecount - 1].x,
3817 state[statecount - 1].pane,
3769 faces, 1); 3818 faces, 1);
3770 } 3819 }
3771 else 3820 else
3772 { 3821 {
3773 if ((menu_help_message || prev_menu_help_message) 3822 if ((menu_help_message || prev_menu_help_message)
3774 && menu_help_message != prev_menu_help_message) 3823 && menu_help_message != prev_menu_help_message)
3775 { 3824 {
3776 help_callback (menu_help_message); 3825 help_callback (menu_help_message,
3826 menu_help_paneno, menu_help_itemno);
3777 IT_display_cursor (0); 3827 IT_display_cursor (0);
3778 prev_menu_help_message = menu_help_message; 3828 prev_menu_help_message = menu_help_message;
3779 } 3829 }
3780 /* We are busy-waiting for the mouse to move, so let's be nice 3830 /* We are busy-waiting for the mouse to move, so let's be nice
3781 to other Windows applications by releasing our time slice. */ 3831 to other Windows applications by releasing our time slice. */
5112 syms_of_msdos () 5162 syms_of_msdos ()
5113 { 5163 {
5114 recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil); 5164 recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil);
5115 staticpro (&recent_doskeys); 5165 staticpro (&recent_doskeys);
5116 #ifndef HAVE_X_WINDOWS 5166 #ifndef HAVE_X_WINDOWS
5167 help_echo = Qnil;
5117 staticpro (&help_echo); 5168 staticpro (&help_echo);
5118 help_echo = Qnil; 5169 help_echo_object = Qnil;
5170 staticpro (&help_echo_object);
5171 help_echo_window = Qnil;
5172 staticpro (&help_echo_window);
5173 previous_help_echo = Qnil;
5119 staticpro (&previous_help_echo); 5174 staticpro (&previous_help_echo);
5120 previous_help_echo = Qnil; 5175 help_echo_pos = -1;
5121 5176
5122 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, 5177 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
5123 "List of directories to search for bitmap files for X."); 5178 "List of directories to search for bitmap files for X.");
5124 Vx_bitmap_file_path = decode_env_path ((char *) 0, "."); 5179 Vx_bitmap_file_path = decode_env_path ((char *) 0, ".");
5125 5180