X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9d66f88eb9f67c5484abb4000e2d5e6acf34a795..412f24b9ddf1e07022f8c5fe05f0717f130c4c02:/src/xmenu.c diff --git a/src/xmenu.c b/src/xmenu.c index c79db086df..fc629b3510 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -108,27 +108,24 @@ along with GNU Emacs. If not, see . */ #ifndef TRUE #define TRUE 1 -#define FALSE 0 #endif /* no TRUE */ -Lisp_Object Qdebug_on_next_call; +static Lisp_Object Qdebug_on_next_call; #if defined (USE_X_TOOLKIT) || defined (USE_GTK) static Lisp_Object xdialog_show (FRAME_PTR, int, Lisp_Object, Lisp_Object, const char **); #endif - -static int update_frame_menubar (struct frame *); /* Flag which when set indicates a dialog or menu has been posted by Xt on behalf of one of the widget sets. */ static int popup_activated_flag; -static int next_menubar_widget_id; - #ifdef USE_X_TOOLKIT +static int next_menubar_widget_id; + /* Return the frame whose ->output_data.x->id equals ID, or 0 if none. */ static struct frame * @@ -243,7 +240,7 @@ for instance using the window manager, then this produces a quit and FRAME_PTR new_f = SELECTED_FRAME (); Lisp_Object bar_window; enum scroll_bar_part part; - unsigned long time; + Time time; Lisp_Object x, y; (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time); @@ -341,7 +338,7 @@ for instance using the window manager, then this produces a quit and unbind_to (specpdl_count, Qnil); discard_menu_items (); - if (error_name) error (error_name); + if (error_name) error ("%s", error_name); return selection; } #endif @@ -350,6 +347,8 @@ for instance using the window manager, then this produces a quit and #ifndef MSDOS +#if defined USE_GTK || defined USE_MOTIF + /* Set menu_items_inuse so no other popup menu or dialog is created. */ void @@ -363,8 +362,13 @@ x_menu_set_in_use (int in_use) #endif } +#endif + /* Wait for an X event to arrive or for a timer to expire. */ +#ifndef USE_MOTIF +static +#endif void x_menu_wait_for_event (void *data) { @@ -383,7 +387,7 @@ x_menu_wait_for_event (void *data) #endif ) { - EMACS_TIME next_time = timer_check (1), *ntp; + EMACS_TIME next_time = timer_check (), *ntp; long secs = EMACS_SECS (next_time); long usecs = EMACS_USECS (next_time); SELECT_TYPE read_fds; @@ -712,7 +716,7 @@ show_help_event (FRAME_PTR f, xt_or_gtk_widget widget, Lisp_Object help) break; } #endif - show_help_echo (help, Qnil, Qnil, Qnil, 1); + show_help_echo (help, Qnil, Qnil, Qnil); } } @@ -922,7 +926,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) #endif Lisp_Object items; widget_value *wv, *first_wv, *prev_wv = 0; - int i, last_i = 0; + int i; int *submenu_start, *submenu_end; int *submenu_top_level_items, *submenu_n_panes; @@ -966,6 +970,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) Lisp_Object *previous_items = (Lisp_Object *) alloca (previous_menu_items_used * sizeof (Lisp_Object)); + int subitems; /* If we are making a new widget, its contents are empty, do always reinitialize them. */ @@ -1010,21 +1015,19 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) menu_items = f->menu_bar_vector; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; - submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); - submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); - submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int)); - submenu_top_level_items - = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); + subitems = ASIZE (items) / 4; + submenu_start = (int *) alloca ((subitems + 1) * sizeof (int)); + submenu_end = (int *) alloca (subitems * sizeof (int)); + submenu_n_panes = (int *) alloca (subitems * sizeof (int)); + submenu_top_level_items = (int *) alloca (subitems * sizeof (int)); init_menu_items (); - for (i = 0; i < XVECTOR (items)->size; i += 4) + for (i = 0; i < subitems; i++) { Lisp_Object key, string, maps; - last_i = i; - - key = XVECTOR (items)->contents[i]; - string = XVECTOR (items)->contents[i + 1]; - maps = XVECTOR (items)->contents[i + 2]; + key = XVECTOR (items)->contents[4 * i]; + string = XVECTOR (items)->contents[4 * i + 1]; + maps = XVECTOR (items)->contents[4 * i + 2]; if (NILP (string)) break; @@ -1038,6 +1041,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) submenu_end[i] = menu_items_used; } + submenu_start[i] = -1; finish_menu_items (); /* Convert menu_items into widget_value trees @@ -1051,7 +1055,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) wv->help = Qnil; first_wv = wv; - for (i = 0; i < last_i; i += 4) + for (i = 0; 0 <= submenu_start[i]; i++) { menu_items_n_panes = submenu_n_panes[i]; wv = digest_single_submenu (submenu_start[i], submenu_end[i], @@ -1096,7 +1100,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) /* Now GC cannot happen during the lifetime of the widget_value, so it's safe to store data from a Lisp_String. */ wv = first_wv->contents; - for (i = 0; i < XVECTOR (items)->size; i += 4) + for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object string; string = XVECTOR (items)->contents[i + 1]; @@ -1122,7 +1126,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) first_wv = wv; items = FRAME_MENU_BAR_ITEMS (f); - for (i = 0; i < XVECTOR (items)->size; i += 4) + for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object string; @@ -1138,9 +1142,9 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) wv->help = Qnil; /* This prevents lwlib from assuming this menu item is really supposed to be empty. */ - /* The EMACS_INT cast avoids a warning. + /* The intptr_t cast avoids a warning. This value just has to be different from small integers. */ - wv->call_data = (void *) (EMACS_INT) (-1); + wv->call_data = (void *) (intptr_t) (-1); if (prev_wv) prev_wv->next = wv; @@ -1388,7 +1392,7 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer /* Check if there is room for the menu. If not, adjust x/y so that the menu is fully visible. */ - gtk_widget_size_request (GTK_WIDGET (menu), &req); + gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &req); if (data->x + req.width > disp_width) *x -= data->x + req.width - disp_width; if (data->y + req.height > disp_height) @@ -1420,7 +1424,8 @@ pop_down_menu (Lisp_Object arg) menu pops down. menu_item_selection will be set to the selection. */ static void -create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, int for_click, EMACS_UINT timestamp) +create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, + int for_click, Time timestamp) { int i; GtkWidget *menu; @@ -1464,7 +1469,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, i gtk_widget_show_all (menu); gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, - timestamp > 0 ? timestamp : gtk_get_current_event_time()); + timestamp ? timestamp : gtk_get_current_event_time ()); record_unwind_protect (pop_down_menu, make_save_value (menu, 0)); @@ -1524,12 +1529,13 @@ pop_down_menu (Lisp_Object arg) menu_item_selection will be set to the selection. */ static void create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, - int x, int y, int for_click, EMACS_UINT timestamp) + int x, int y, int for_click, Time timestamp) { int i; Arg av[2]; int ac = 0; - XButtonPressedEvent dummy; + XEvent dummy; + XButtonPressedEvent *event = &(dummy.xbutton); LWLIB_ID menu_id; Widget menu; @@ -1547,36 +1553,35 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, popup_deactivate_callback, menu_highlight_callback); - dummy.type = ButtonPress; - dummy.serial = 0; - dummy.send_event = 0; - dummy.display = FRAME_X_DISPLAY (f); - dummy.time = CurrentTime; - dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window; - dummy.window = dummy.root; - dummy.subwindow = dummy.root; - dummy.x = x; - dummy.y = y; + event->type = ButtonPress; + event->serial = 0; + event->send_event = 0; + event->display = FRAME_X_DISPLAY (f); + event->time = CurrentTime; + event->root = FRAME_X_DISPLAY_INFO (f)->root_window; + event->window = event->subwindow = event->root; + event->x = x; + event->y = y; /* Adjust coordinates to be root-window-relative. */ x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); - dummy.x_root = x; - dummy.y_root = y; + event->x_root = x; + event->y_root = y; - dummy.state = 0; - dummy.button = 0; + event->state = 0; + event->button = 0; for (i = 0; i < 5; i++) if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i)) - dummy.button = i; + event->button = i; /* Don't allow any geometry request from the user. */ XtSetArg (av[ac], XtNgeometry, 0); ac++; XtSetValues (menu, av, ac); /* Display the menu. */ - lw_popup_menu (menu, (XEvent *) &dummy); + lw_popup_menu (menu, &dummy); popup_activated_flag = 1; x_activate_timeout_atimer (); @@ -1598,7 +1603,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, Lisp_Object xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, - Lisp_Object title, const char **error, EMACS_UINT timestamp) + Lisp_Object title, const char **error_name, Time timestamp) { int i; widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; @@ -1613,11 +1618,11 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, if (! FRAME_X_P (f)) abort (); - *error = NULL; + *error_name = NULL; if (menu_items_used <= MENU_ITEMS_PANE_LENGTH) { - *error = "Empty menu"; + *error_name = "Empty menu"; return Qnil; } @@ -1662,7 +1667,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, { /* Create a new pane. */ Lisp_Object pane_name, prefix; - char *pane_string; + const char *pane_string; pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); @@ -1875,9 +1880,9 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, static void dialog_selection_callback (GtkWidget *widget, gpointer client_data) { - /* The EMACS_INT cast avoids a warning. There's no problem + /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((int) (EMACS_INT) client_data != -1) + if ((intptr_t) client_data != -1) menu_item_selection = (Lisp_Object *) client_data; popup_activated_flag = 0; @@ -1918,9 +1923,9 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) static void dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) { - /* The EMACS_INT cast avoids a warning. There's no problem + /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((int) (EMACS_INT) client_data != -1) + if ((intptr_t) client_data != -1) menu_item_selection = (Lisp_Object *) client_data; BLOCK_INPUT; @@ -2010,7 +2015,7 @@ xdialog_show (FRAME_PTR f, representing the text label and buttons. */ { Lisp_Object pane_name, prefix; - char *pane_string; + const char *pane_string; pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME]; prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX]; pane_string = (NILP (pane_name) @@ -2181,7 +2186,7 @@ static struct frame *menu_help_frame; keyboard events. */ static void -menu_help_callback (char *help_string, int pane, int item) +menu_help_callback (char const *help_string, int pane, int item) { Lisp_Object *first_item; Lisp_Object pane_name; @@ -2201,7 +2206,7 @@ menu_help_callback (char *help_string, int pane, int item) Fcons (pane_name, Fcons (make_number (pane), Qnil))); show_help_echo (help_string ? build_string (help_string) : Qnil, - Qnil, menu_object, make_number (item), 1); + Qnil, menu_object, make_number (item)); } static Lisp_Object @@ -2241,7 +2246,7 @@ pop_down_menu (Lisp_Object arg) Lisp_Object xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, - Lisp_Object title, const char **error, EMACS_UINT timestamp) + Lisp_Object title, const char **error_name, Time timestamp) { Window root; XMenu *menu; @@ -2259,13 +2264,13 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f)) abort (); - *error = 0; + *error_name = 0; if (menu_items_n_panes == 0) return Qnil; if (menu_items_used <= MENU_ITEMS_PANE_LENGTH) { - *error = "Empty menu"; + *error_name = "Empty menu"; return Qnil; } @@ -2278,7 +2283,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, menu = XMenuCreate (FRAME_X_DISPLAY (f), root, "emacs"); if (menu == NULL) { - *error = "Can't create menu"; + *error_name = "Can't create menu"; return Qnil; } @@ -2298,14 +2303,15 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, y += f->top_pos; /* Create all the necessary panes and their items. */ - maxlines = lines = i = 0; + maxwidth = maxlines = lines = i = 0; + lpane = XM_FAILURE; while (i < menu_items_used) { if (EQ (XVECTOR (menu_items)->contents[i], Qt)) { /* Create a new pane. */ Lisp_Object pane_name, prefix; - char *pane_string; + const char *pane_string; maxlines = max (maxlines, lines); lines = 0; @@ -2320,13 +2326,12 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, if (lpane == XM_FAILURE) { XMenuDestroy (FRAME_X_DISPLAY (f), menu); - *error = "Can't create pane"; + *error_name = "Can't create pane"; return Qnil; } i += MENU_ITEMS_PANE_LENGTH; /* Find the width of the widest item in this pane. */ - maxwidth = 0; j = i; while (j < menu_items_used) { @@ -2354,40 +2359,38 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, { /* Create a new item within current pane. */ Lisp_Object item_name, enable, descrip, help; - unsigned char *item_data; - char *help_string; + char *item_data; + char const *help_string; item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; descrip = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; - help_string = STRINGP (help) ? SDATA (help) : NULL; + help_string = STRINGP (help) ? SSDATA (help) : NULL; if (!NILP (descrip)) { - int gap = maxwidth - SBYTES (item_name); /* if alloca is fast, use that to make the space, to reduce gc needs. */ - item_data - = (unsigned char *) alloca (maxwidth - + SBYTES (descrip) + 1); - memcpy (item_data, SDATA (item_name), SBYTES (item_name)); + item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1); + memcpy (item_data, SSDATA (item_name), SBYTES (item_name)); for (j = SCHARS (item_name); j < maxwidth; j++) item_data[j] = ' '; - memcpy (item_data + j, SDATA (descrip), SBYTES (descrip)); + memcpy (item_data + j, SSDATA (descrip), SBYTES (descrip)); item_data[j + SBYTES (descrip)] = 0; } else - item_data = SDATA (item_name); + item_data = SSDATA (item_name); - if (XMenuAddSelection (FRAME_X_DISPLAY (f), - menu, lpane, 0, item_data, - !NILP (enable), help_string) - == XM_FAILURE) + if (lpane == XM_FAILURE + || (XMenuAddSelection (FRAME_X_DISPLAY (f), + menu, lpane, 0, item_data, + !NILP (enable), help_string) + == XM_FAILURE)) { XMenuDestroy (FRAME_X_DISPLAY (f), menu); - *error = "Can't add selection to menu"; + *error_name = "Can't add selection to menu"; return Qnil; } i += MENU_ITEMS_ITEM_LENGTH; @@ -2464,6 +2467,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, x, y, ButtonReleaseMask, &datap, menu_help_callback); + entry = pane_prefix = Qnil; switch (status) { @@ -2508,16 +2512,14 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, break; case XM_FAILURE: - *error = "Can't activate menu"; + *error_name = "Can't activate menu"; case XM_IA_SELECT: - entry = Qnil; break; case XM_NO_SELECT: /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means the menu was invoked with a mouse event as POSITION). */ if (! for_click) Fsignal (Qquit, Qnil); - entry = Qnil; break; } @@ -2557,8 +2559,7 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ void syms_of_xmenu (void) { - Qdebug_on_next_call = intern_c_string ("debug-on-next-call"); - staticpro (&Qdebug_on_next_call); + DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); #ifdef USE_X_TOOLKIT widget_id_tick = (1<<16);