Mercurial > emacs
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 |