X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/015936fba1bcaa51b7886a73144d4c088200c0aa..924a09e9161c05d9d69d85fa102910b10ece372f:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index 81496f35bf..5edb635b18 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -24,6 +24,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "xterm.h" +#include "menu.h" #include "frame.h" #include "window.h" #include "character.h" @@ -124,7 +125,6 @@ extern LWLIB_ID widget_id_tick; #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) -static Lisp_Object Qsuppress_icon; static Lisp_Object Qundefined_color; static Lisp_Object Qcompound_text, Qcancel_timer; Lisp_Object Qfont_param; @@ -159,7 +159,7 @@ check_x_display_info (Lisp_Object object) } else if (TERMINALP (object)) { - struct terminal *t = get_terminal (object, 1); + struct terminal *t = decode_live_terminal (object); if (t->type != output_x_window) error ("Terminal %d is not an X display", t->id); @@ -329,8 +329,43 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) *yptr = real_y; } - +/* Get the mouse position in frame relative coordinates. */ + +void +x_relative_mouse_position (struct frame *f, int *x, int *y) +{ + Window root, dummy_window; + int dummy; + + eassert (FRAME_X_P (f)); + + block_input (); + + XQueryPointer (FRAME_X_DISPLAY (f), + DefaultRootWindow (FRAME_X_DISPLAY (f)), + + /* The root window which contains the pointer. */ + &root, + + /* Window pointer is on, not used */ + &dummy_window, + + /* The position on that root window. */ + x, y, + + /* x/y in dummy_window coordinates, not used. */ + &dummy, &dummy, + /* Modifier keys and pointer buttons, about which + we don't care. */ + (unsigned int *) &dummy); + + unblock_input (); + + /* Translate root window coordinates to window coordinates. */ + *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); + *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); +} /* Gamma-correct COLOR on frame F. */ @@ -422,15 +457,23 @@ x_set_tool_bar_position (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) { - if (! EQ (new_value, Qleft) && ! EQ (new_value, Qright) - && ! EQ (new_value, Qbottom) && ! EQ (new_value, Qtop)) - return; - if (EQ (new_value, old_value)) return; + Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom); + if (!NILP (Fmemq (new_value, choice))) + { #ifdef USE_GTK - xg_change_toolbar_position (f, new_value); - fset_tool_bar_position (f, new_value); + if (!EQ (new_value, old_value)) + { + xg_change_toolbar_position (f, new_value); + fset_tool_bar_position (f, new_value); + } +#else + if (!EQ (new_value, Qtop)) + error ("The only supported tool bar position is top"); #endif + } + else + wrong_choice (choice, new_value); } #ifdef USE_GTK @@ -922,7 +965,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) } -void +static void x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { int nlines; @@ -966,7 +1009,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) #else /* not USE_X_TOOLKIT && not USE_GTK */ FRAME_MENU_BAR_LINES (f) = nlines; FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); - resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); + adjust_frame_size (f, -1, -1, 2, 1); if (FRAME_X_WINDOW (f)) x_clear_under_internal_border (f); @@ -1017,14 +1060,10 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) height of all windows on frame F to match the new tool bar height. The frame's height doesn't change. */ -void +static void x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { int nlines; -#if ! defined (USE_GTK) - int delta, root_height; - int unit = FRAME_LINE_HEIGHT (f); -#endif /* Treat tool bars like menu bars. */ if (FRAME_MINIBUF_ONLY_P (f)) @@ -1036,11 +1075,18 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) else nlines = 0; -#ifdef USE_GTK + x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); +} + +/* Set the pixel height of the tool bar of frame F to HEIGHT. */ +void +x_change_tool_bar_height (struct frame *f, int height) +{ +#ifdef USE_GTK FRAME_TOOL_BAR_LINES (f) = 0; FRAME_TOOL_BAR_HEIGHT (f) = 0; - if (nlines) + if (height) { FRAME_EXTERNAL_TOOL_BAR (f) = 1; if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0) @@ -1054,39 +1100,25 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) free_frame_tool_bar (f); FRAME_EXTERNAL_TOOL_BAR (f) = 0; } - #else /* !USE_GTK */ + int unit = FRAME_LINE_HEIGHT (f); + int old_height = FRAME_TOOL_BAR_HEIGHT (f); + int lines = (height + unit - 1) / unit; /* Make sure we redisplay all windows in this frame. */ windows_or_buffers_changed = 60; - /* DELTA is in pixels now. */ - delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit; - /* Don't resize the tool-bar to more than we have room for. Note: The - calculations below and the subsequent call to resize_frame_windows - are inherently flawed because they can make the toolbar higher than - the containing frame. */ - if (delta > 0) - { - root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); - if (root_height - delta < unit) - { - delta = root_height - unit; - /* When creating a new frame and toolbar mode is enabled, we - need at least one toolbar line. */ - nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1); - } - } - - FRAME_TOOL_BAR_LINES (f) = nlines; - FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); - resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); -#if !defined USE_X_TOOLKIT && !defined USE_GTK - if (FRAME_X_WINDOW (f)) - x_clear_under_internal_border (f); -#endif - adjust_frame_glyphs (f); + /* Recalculate tool bar and frame text sizes. */ + FRAME_TOOL_BAR_HEIGHT (f) = height; + FRAME_TOOL_BAR_LINES (f) = lines; + FRAME_TEXT_HEIGHT (f) + = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); + FRAME_LINES (f) + = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); + /* Store the `tool-bar-lines' and `height' frame parameters. */ + store_frame_param (f, Qtool_bar_lines, make_number (lines)); + store_frame_param (f, Qheight, make_number (FRAME_LINES (f))); /* We also have to make sure that the internal border at the top of the frame, below the menu bar or tool bar, is redrawn when the @@ -1100,30 +1132,50 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) clear_current_matrices (f); } - /* If the tool bar gets smaller, the internal border below it - has to be cleared. It was formerly part of the display - of the larger tool bar, and updating windows won't clear it. */ - if (delta < 0) + if ((height < old_height) && WINDOWP (f->tool_bar_window)) + clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); + + /* Recalculate toolbar height. */ + f->n_tool_bar_rows = 0; + + adjust_frame_size (f, -1, -1, 4, 0); + + if (FRAME_X_WINDOW (f)) + x_clear_under_internal_border (f); + +#endif /* USE_GTK */ +} + + +static void +x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + int border; + + CHECK_TYPE_RANGED_INTEGER (int, arg); + border = max (XINT (arg), 0); + + if (border != FRAME_INTERNAL_BORDER_WIDTH (f)) { - int height = FRAME_INTERNAL_BORDER_WIDTH (f); - int width = FRAME_PIXEL_WIDTH (f); - int y = nlines * unit; + FRAME_INTERNAL_BORDER_WIDTH (f) = border; - /* height can be zero here. */ - if (height > 0 && width > 0) +#ifdef USE_X_TOOLKIT + if (FRAME_X_OUTPUT (f)->edit_widget) + widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget); +#endif + + if (FRAME_X_WINDOW (f) != 0) { - block_input (); - x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - 0, y, width, height); - unblock_input (); - } + adjust_frame_size (f, -1, -1, 3, 0); - if (WINDOWP (f->tool_bar_window)) - clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); +#ifdef USE_GTK + xg_clear_under_internal_border (f); +#else + x_clear_under_internal_border (f); +#endif + } } - run_window_configuration_change_hook (f); -#endif /* USE_GTK */ } @@ -1178,7 +1230,7 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old if (f->output_data.x->scroll_bar_background_pixel != -1) unload_color (f, f->output_data.x->scroll_bar_background_pixel); -#ifdef USE_TOOLKIT_SCROLL_BARS +#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS) /* Scrollbar shadow colors. */ if (f->output_data.x->scroll_bar_top_shadow_pixel != -1) { @@ -1190,7 +1242,7 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel); f->output_data.x->scroll_bar_bottom_shadow_pixel = -1; } -#endif /* USE_TOOLKIT_SCROLL_BARS */ +#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ f->output_data.x->scroll_bar_background_pixel = pixel; if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) @@ -1217,10 +1269,6 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old CODING_SYSTEM, and return a newly allocated memory area which should be freed by `xfree' by a caller. - SELECTIONP non-zero means the string is being encoded for an X - selection, so it is safe to run pre-write conversions (which - may run Lisp code). - Store the byte length of resulting text in *TEXT_BYTES. If the text contains only ASCII and Latin-1, store 1 in *STRING_P, @@ -1229,8 +1277,8 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old the result should be `COMPOUND_TEXT'. */ static unsigned char * -x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, - ptrdiff_t *text_bytes, int *stringp, int *freep) +x_encode_text (Lisp_Object string, Lisp_Object coding_system, + ptrdiff_t *text_bytes, int *stringp, bool *freep) { int result = string_xstring_p (string); struct coding_system coding; @@ -1273,7 +1321,7 @@ x_set_name_internal (struct frame *f, Lisp_Object name) XTextProperty text, icon; ptrdiff_t bytes; int stringp; - int do_free_icon_value = 0, do_free_text_value = 0; + bool do_free_icon_value = 0, do_free_text_value = 0; Lisp_Object coding_system; Lisp_Object encoded_name; Lisp_Object encoded_icon_name; @@ -1305,14 +1353,12 @@ x_set_name_internal (struct frame *f, Lisp_Object name) properties. Per the EWMH specification, those two properties are always UTF8_STRING. This matches what gtk_window_set_title() does in the USE_GTK case. */ - text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp, - &do_free_text_value); + text.value = x_encode_text (name, coding_system, &bytes, + &stringp, &do_free_text_value); text.encoding = (stringp ? XA_STRING : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); text.format = 8; text.nitems = bytes; - if (text.nitems != bytes) - error ("Window name too large"); if (!STRINGP (f->icon_name)) { @@ -1322,14 +1368,12 @@ x_set_name_internal (struct frame *f, Lisp_Object name) else { /* See the above comment "Note: Encoding strategy". */ - icon.value = x_encode_text (f->icon_name, coding_system, 0, - &bytes, &stringp, &do_free_icon_value); + icon.value = x_encode_text (f->icon_name, coding_system, &bytes, + &stringp, &do_free_icon_value); icon.encoding = (stringp ? XA_STRING : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); icon.format = 8; icon.nitems = bytes; - if (icon.nitems != bytes) - error ("Icon name too large"); encoded_icon_name = ENCODE_UTF_8 (f->icon_name); } @@ -1367,16 +1411,16 @@ x_set_name_internal (struct frame *f, Lisp_Object name) /* Change the name of frame F to NAME. If NAME is nil, set F's name to x_id_name. - If EXPLICIT is non-zero, that indicates that lisp code is setting the + If EXPLICIT is true, that indicates that lisp code is setting the name; if NAME is a string, set F's name to NAME and set F->explicit_name; if NAME is Qnil, then clear F->explicit_name. - If EXPLICIT is zero, that indicates that Emacs redisplay code is + If EXPLICIT is false, that indicates that Emacs redisplay code is suggesting a new name, which lisp code should override; if F->explicit_name is set, ignore the new name; otherwise, set it. */ static void -x_set_name (struct frame *f, Lisp_Object name, int explicit) +x_set_name (struct frame *f, Lisp_Object name, bool explicit) { /* Make sure that requests from lisp code override requests from Emacs redisplay code. */ @@ -1473,14 +1517,36 @@ x_set_scroll_bar_default_width (struct frame *f) FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit; FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw; #else - /* The width of a non-toolkit scrollbar is at least 14 pixels and a - multiple of the frame's character width. */ + /* The width of a non-toolkit scrollbar is 14 pixels. */ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit; FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit; #endif } +void +x_set_scroll_bar_default_height (struct frame *f) +{ + int height = FRAME_LINE_HEIGHT (f); +#ifdef USE_TOOLKIT_SCROLL_BARS +#ifdef USE_GTK + int min_height = xg_get_default_scrollbar_height (); +#else + int min_height = 16; +#endif + /* A minimum height of 14 doesn't look good for toolkit scroll bars. */ + FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height; + FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height; +#else + /* The height of a non-toolkit scrollbar is 14 pixels. */ + FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height; + + /* Use all of that space (aside from required margins) for the + scroll bar. */ + FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14; +#endif +} + /* Record in frame F the specified or default value according to ALIST of the parameter named PROP (a Lisp symbol). If no value is @@ -1503,13 +1569,14 @@ x_default_scroll_bar_color_parameter (struct frame *f, /* See if an X resource for the scroll bar color has been specified. */ - tem = display_x_get_resource (dpyinfo, - build_string (foreground_p - ? "foreground" - : "background"), - empty_unibyte_string, - build_string ("verticalScrollBar"), - empty_unibyte_string); + AUTO_STRING (foreground, "foreground"); + AUTO_STRING (background, "foreground"); + AUTO_STRING (verticalScrollBar, "verticalScrollBar"); + tem = (display_x_get_resource + (dpyinfo, foreground_p ? foreground : background, + empty_unibyte_string, + verticalScrollBar, + empty_unibyte_string)); if (!STRINGP (tem)) { /* If nothing has been specified, scroll bars will use a @@ -1527,7 +1594,8 @@ x_default_scroll_bar_color_parameter (struct frame *f, #endif /* not USE_TOOLKIT_SCROLL_BARS */ } - x_set_frame_parameters (f, list1 (Fcons (prop, tem))); + AUTO_FRAME_ARG (arg, prop, tem); + x_set_frame_parameters (f, arg); return tem; } @@ -1560,7 +1628,7 @@ hack_wm_protocols (struct frame *f, Widget widget) if ((XGetWindowProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols, - (long)0, (long)100, False, XA_ATOM, + 0, 100, False, XA_ATOM, &type, &format, &nitems, &bytes_after, &catoms) == Success) @@ -1718,7 +1786,7 @@ xic_create_fontsetname (const char *base_fontname, int motif) len = p - base_fontname + strlen (allcs) + 1; font_allcs = alloca (len); memcpy (font_allcs, base_fontname, p - base_fontname); - strcat (font_allcs, allcs); + strcpy (font_allcs + (p - base_fontname), allcs); /* Build the font spec that matches all families and add-styles. */ @@ -1726,7 +1794,7 @@ xic_create_fontsetname (const char *base_fontname, int motif) font_allfamilies = alloca (len); strcpy (font_allfamilies, allfamilies); memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1); - strcat (font_allfamilies, allcs); + strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs); /* Build the font spec that matches all. */ len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1; @@ -1734,7 +1802,8 @@ xic_create_fontsetname (const char *base_fontname, int motif) strcpy (font_all, allfamilies); strcat (font_all, all); memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2); - strcat (font_all, allcs); + strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2), + allcs); /* Build the actual font set name. */ len = strlen (base_fontname) + strlen (font_allcs) @@ -2220,8 +2289,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) /* Do some needed geometry management. */ { - char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)]; - Arg gal[10]; + Arg gal[3]; int gac = 0; int extra_borders = 0; int menubar_size @@ -2240,7 +2308,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) } #endif - f->output_data.x->menubar_height = menubar_size; + FRAME_MENUBAR_HEIGHT (f) = menubar_size; #ifndef USE_LUCID /* Motif seems to need this amount added to the sizes @@ -2251,6 +2319,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) extra_borders *= 2; #endif + f->shell_position = xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)); + /* Convert our geometry parameters into a geometry string and specify it. Note that we do not specify here whether the position @@ -2267,14 +2337,14 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) top = -top; if (window_prompting & USPosition) - sprintf (shell_position, "=%dx%d%c%d%c%d", + sprintf (f->shell_position, "=%dx%d%c%d%c%d", FRAME_PIXEL_WIDTH (f) + extra_borders, FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders, (xneg ? '-' : '+'), left, (yneg ? '-' : '+'), top); else { - sprintf (shell_position, "=%dx%d", + sprintf (f->shell_position, "=%dx%d", FRAME_PIXEL_WIDTH (f) + extra_borders, FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders); @@ -2288,12 +2358,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) } } - /* We don't free this because we don't know whether - it is safe to free it while the frame exists. - It isn't worth the trouble of arranging to free it - when the frame is deleted. */ - tem = xstrdup (shell_position); - XtSetArg (gal[gac], XtNgeometry, tem); gac++; + XtSetArg (gal[gac], XtNgeometry, f->shell_position); gac++; XtSetValues (shell_widget, gal, gac); } @@ -2362,7 +2427,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) the X server hasn't been told. */ { Lisp_Object name; - int explicit = f->explicit_name; + bool explicit = f->explicit_name; f->explicit_name = 0; name = f->name; @@ -2476,10 +2541,6 @@ x_window (struct frame *f) class_hints.res_class = SSDATA (Vx_resource_class); XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints); - /* The menubar is part of the ordinary display; - it does not count in addition to the height of the window. */ - f->output_data.x->menubar_height = 0; - /* This indicates that we use the "Passive Input" input model. Unless we do this, we don't get the Focus{In,Out} events that we need to draw the cursor correctly. Accursed bureaucrats. @@ -2505,7 +2566,7 @@ x_window (struct frame *f) the X server hasn't been told. */ { Lisp_Object name; - int explicit = f->explicit_name; + bool explicit = f->explicit_name; f->explicit_name = 0; name = f->name; @@ -2728,12 +2789,6 @@ do_unwind_create_frame (Lisp_Object frame) unwind_create_frame (frame); } -static void -unwind_create_frame_1 (Lisp_Object val) -{ - inhibit_lisp_code = val; -} - static void x_default_font_parameter (struct frame *f, Lisp_Object parms) { @@ -2792,7 +2847,8 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms) { /* Remember the explicit font parameter, so we can re-apply it after we've applied the `default' face settings. */ - x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param))); + AUTO_FRAME_ARG (arg, Qfont_param, font_param); + x_set_frame_parameters (f, arg); } /* This call will make X resources override any system font setting. */ @@ -2818,29 +2874,31 @@ Signal error if FRAME is not an X frame. */) static void set_machine_and_pid_properties (struct frame *f) { - long pid = (long) getpid (); - /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */ XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL, NULL, 0, NULL, NULL, NULL); - XChangeProperty (FRAME_X_DISPLAY (f), - FRAME_OUTER_WINDOW (f), - XInternAtom (FRAME_X_DISPLAY (f), - "_NET_WM_PID", - False), - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &pid, 1); + pid_t pid = getpid (); + if (pid <= 0xffffffffu) + { + unsigned long xpid = pid; + XChangeProperty (FRAME_X_DISPLAY (f), + FRAME_OUTER_WINDOW (f), + XInternAtom (FRAME_X_DISPLAY (f), + "_NET_WM_PID", + False), + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &xpid, 1); + } } DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, doc: /* Make a new X window, which is called a "frame" in Emacs terms. -Return an Emacs frame object. -PARMS is an alist of frame parameters. +Return an Emacs frame object. PARMS is an alist of frame parameters. If the parameters specify that the frame should not have a minibuffer, -and do not specify a specific minibuffer window to use, -then `default-minibuffer-frame' must be a frame whose minibuffer can -be shared by the new frame. +and do not specify a specific minibuffer window to use, then +`default-minibuffer-frame' must be a frame whose minibuffer can be +shared by the new frame. This function is an internal primitive--use `make-frame' instead. */) (Lisp_Object parms) @@ -2850,7 +2908,6 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object name; int minibuffer_only = 0; long window_prompting = 0; - int width, height; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; Lisp_Object display; @@ -2920,10 +2977,10 @@ This function is an internal primitive--use `make-frame' instead. */) FRAME_FONTSET (f) = -1; f->output_data.x->scroll_bar_foreground_pixel = -1; f->output_data.x->scroll_bar_background_pixel = -1; -#ifdef USE_TOOLKIT_SCROLL_BARS +#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS) f->output_data.x->scroll_bar_top_shadow_pixel = -1; f->output_data.x->scroll_bar_bottom_shadow_pixel = -1; -#endif /* USE_TOOLKIT_SCROLL_BARS */ +#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ f->output_data.x->white_relief.pixel = -1; f->output_data.x->black_relief.pixel = -1; @@ -2972,7 +3029,6 @@ This function is an internal primitive--use `make-frame' instead. */) } /* Specify the parent under which to make this X window. */ - if (!NILP (parent)) { f->output_data.x->parent_desc = (Window) XFASTINT (parent); @@ -2995,7 +3051,7 @@ This function is an internal primitive--use `make-frame' instead. */) { fset_name (f, name); f->explicit_name = 1; - /* use the frame's title when getting resources for this frame. */ + /* Use the frame's title when getting resources for this frame. */ specbind (Qx_resource_name, name); } @@ -3058,7 +3114,9 @@ This function is an internal primitive--use `make-frame' instead. */) #endif "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); - + x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil, + "horizontalScrollBars", "ScrollBars", + RES_TYPE_SYMBOL); /* Also do the stuff which must be set before the window exists. */ x_default_parameter (f, parms, Qforeground_color, build_string ("black"), "foreground", "Foreground", RES_TYPE_STRING); @@ -3090,49 +3148,36 @@ This function is an internal primitive--use `make-frame' instead. */) dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ - /* Init faces before x_default_parameter is called for scroll-bar - parameters because that function calls x_set_scroll_bar_width, - which calls change_frame_size, which calls Fset_window_buffer, - which runs hooks, which call Fvertical_motion. At the end, we - end up in init_iterator with a null face cache, which should not - happen. */ + /* Init faces before x_default_parameter is called for the + scroll-bar-width parameter because otherwise we end up in + init_iterator with a null face cache, which should not happen. */ init_frame_faces (f); - /* PXW: This is a duplicate from below. We have to do it here since - otherwise x_set_tool_bar_lines will work with the character sizes - installed by init_frame_faces while the frame's pixel size is still - calculated from a character size of 1 and we subsequently hit the - eassert (height >= 0) assertion in window_box_height. The - non-pixelwise code apparently worked around this because it had one - frame line vs one toolbar line which left us with a zero root - window height which was obviously wrong as well ... */ - change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1); + /* The following call of change_frame_size is needed since otherwise + x_set_tool_bar_lines will already work with the character sizes + installed by init_frame_faces while the frame's pixel size is + still calculated from a character size of 1 and we subsequently + hit the (height >= 0) assertion in window_box_height. + + The non-pixelwise code apparently worked around this because it + had one frame line vs one toolbar line which left us with a zero + root window height which was obviously wrong as well ... */ + adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); /* Set the menu-bar-lines and tool-bar-lines parameters. We don't look up the X resources controlling the menu-bar and tool-bar here; they are processed specially at startup, and reflected in - the values of the mode variables. + the values of the mode variables. */ - Avoid calling window-configuration-change-hook; otherwise we - could get an infloop in next_frame since the frame is not yet in - Vframe_list. */ - { - ptrdiff_t count2 = SPECPDL_INDEX (); - record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code); - inhibit_lisp_code = Qt; - - x_default_parameter (f, parms, Qmenu_bar_lines, - NILP (Vmenu_bar_mode) - ? make_number (0) : make_number (1), - NULL, NULL, RES_TYPE_NUMBER); - x_default_parameter (f, parms, Qtool_bar_lines, - NILP (Vtool_bar_mode) - ? make_number (0) : make_number (1), - NULL, NULL, RES_TYPE_NUMBER); - - unbind_to (count2, Qnil); - } + x_default_parameter (f, parms, Qmenu_bar_lines, + NILP (Vmenu_bar_mode) + ? make_number (0) : make_number (1), + NULL, NULL, RES_TYPE_NUMBER); + x_default_parameter (f, parms, Qtool_bar_lines, + NILP (Vtool_bar_mode) + ? make_number (0) : make_number (1), + NULL, NULL, RES_TYPE_NUMBER); x_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate", "BufferPredicate", @@ -3142,9 +3187,9 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qwait_for_wm, Qt, "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN); x_default_parameter (f, parms, Qfullscreen, Qnil, - "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); + "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); x_default_parameter (f, parms, Qtool_bar_position, - f->tool_bar_position, 0, 0, RES_TYPE_SYMBOL); + FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); /* Compute the size of the X window. */ window_prompting = x_figure_window_size (f, parms, 1); @@ -3183,17 +3228,16 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qscroll_bar_width, Qnil, "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER); + x_default_parameter (f, parms, Qscroll_bar_height, Qnil, + "scrollBarHeight", "ScrollBarHeight", + RES_TYPE_NUMBER); x_default_parameter (f, parms, Qalpha, Qnil, "alpha", "Alpha", RES_TYPE_NUMBER); - /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. - Change will not be effected unless different from the current - FRAME_LINES (f). */ - width = FRAME_TEXT_WIDTH (f); - height = FRAME_TEXT_HEIGHT (f); - FRAME_TEXT_HEIGHT (f) = 0; - SET_FRAME_WIDTH (f, 0); - change_frame_size (f, width, height, 1, 0, 0, 1); + /* Consider frame official, now. */ + f->official = true; + + adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); #if defined (USE_X_TOOLKIT) || defined (USE_GTK) /* Create the menu bar. */ @@ -4231,13 +4275,13 @@ select_visual (struct x_display_info *dpyinfo) { Display *dpy = dpyinfo->display; Screen *screen = dpyinfo->screen; - Lisp_Object value; /* See if a visual is specified. */ - value = display_x_get_resource (dpyinfo, - build_string ("visualClass"), - build_string ("VisualClass"), - Qnil, Qnil); + AUTO_STRING (visualClass, "visualClass"); + AUTO_STRING (VisualClass, "VisualClass"); + Lisp_Object value = display_x_get_resource (dpyinfo, visualClass, + VisualClass, Qnil, Qnil); + if (STRINGP (value)) { /* VALUE should be of the form CLASS-DEPTH, where CLASS is one @@ -4248,7 +4292,7 @@ select_visual (struct x_display_info *dpyinfo) int i, class = -1; XVisualInfo vinfo; - strcpy (s, SSDATA (value)); + lispstpcpy (s, value); dash = strchr (s, '-'); if (dash) { @@ -4652,7 +4696,6 @@ no value of TYPE (always string in the MS Windows case). */) { struct frame *f = decode_window_system_frame (frame); Atom prop_atom; - int rc; Lisp_Object prop_value = Qnil; Atom target_type = XA_STRING; Window target_window = FRAME_X_WINDOW (f); @@ -4699,123 +4742,13 @@ no value of TYPE (always string in the MS Windows case). */) vector_ret_p, &found); } - + unblock_input (); UNGCPRO; return prop_value; } - - -/*********************************************************************** - Busy cursor - ***********************************************************************/ - -/* Timer function of hourglass_atimer. TIMER is equal to - hourglass_atimer. - - Display an hourglass pointer 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. */ - -void -show_hourglass (struct atimer *timer) -{ - /* 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) - { - struct frame *f = XFRAME (frame); - - if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f)) - { - Display *dpy = FRAME_X_DISPLAY (f); - -#ifdef USE_X_TOOLKIT - if (f->output_data.x->widget) -#else - if (FRAME_OUTER_WINDOW (f)) -#endif - { - f->output_data.x->hourglass_p = 1; - - if (!f->output_data.x->hourglass_window) - { - unsigned long mask = CWCursor; - XSetWindowAttributes attrs; -#ifdef USE_GTK - Window parent = FRAME_X_WINDOW (f); -#else - Window parent = FRAME_OUTER_WINDOW (f); -#endif - attrs.cursor = f->output_data.x->hourglass_cursor; - - f->output_data.x->hourglass_window - = XCreateWindow (dpy, parent, - 0, 0, 32000, 32000, 0, 0, - InputOnly, - CopyFromParent, - mask, &attrs); - } - - XMapRaised (dpy, f->output_data.x->hourglass_window); - XFlush (dpy); - } - } - } - - hourglass_shown_p = 1; - unblock_input (); - } -} - - -/* Hide the hourglass pointer on all frames, if it is currently - shown. */ - -void -hide_hourglass (void) -{ - if (hourglass_shown_p) - { - Lisp_Object rest, frame; - - block_input (); - FOR_EACH_FRAME (rest, frame) - { - struct frame *f = XFRAME (frame); - - if (FRAME_X_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; - } - } - - hourglass_shown_p = 0; - unblock_input (); - } -} - - - /*********************************************************************** Tool tips ***********************************************************************/ @@ -4896,7 +4829,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, f = make_frame (1); XSETFRAME (frame, f); - buffer = Fget_buffer_create (build_string (" *tip*")); + AUTO_STRING (tip, " *tip*"); + buffer = Fget_buffer_create (tip); /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0); @@ -4923,10 +4857,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo, FRAME_FONTSET (f) = -1; f->output_data.x->scroll_bar_foreground_pixel = -1; f->output_data.x->scroll_bar_background_pixel = -1; -#ifdef USE_TOOLKIT_SCROLL_BARS +#if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS) f->output_data.x->scroll_bar_top_shadow_pixel = -1; f->output_data.x->scroll_bar_bottom_shadow_pixel = -1; -#endif /* USE_TOOLKIT_SCROLL_BARS */ +#endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ f->output_data.x->white_relief.pixel = -1; f->output_data.x->black_relief.pixel = -1; @@ -5042,12 +4976,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ - /* Init faces before x_default_parameter is called for scroll-bar - parameters because that function calls x_set_scroll_bar_width, - which calls change_frame_size, which calls Fset_window_buffer, - which runs hooks, which call Fvertical_motion. At the end, we - end up in init_iterator with a null face cache, which should not - happen. */ + /* Init faces before x_default_parameter is called for the + scroll-bar-width parameter because otherwise we end up in + init_iterator with a null face cache, which should not happen. */ init_frame_faces (f); f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; @@ -5104,12 +5035,15 @@ x_create_tip_frame (struct x_display_info *dpyinfo, width = FRAME_COLS (f); height = FRAME_LINES (f); SET_FRAME_COLS (f, 0); - FRAME_LINES (f) = 0; + SET_FRAME_LINES (f, 0); change_frame_size (f, width, height, 1, 0, 0, 0); /* Add `tooltip' frame parameter's default value. */ if (NILP (Fframe_parameter (frame, Qtooltip))) - Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt))); + { + AUTO_FRAME_ARG (arg, Qtooltip, Qt); + Fmodify_frame_parameters (frame, arg); + } /* FIXME - can this be done in a similar way to normal frames? http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */ @@ -5127,7 +5061,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo, disptype = intern ("color"); if (NILP (Fframe_parameter (frame, Qdisplay_type))) - Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype))); + { + AUTO_FRAME_ARG (arg, Qdisplay_type, disptype); + Fmodify_frame_parameters (frame, arg); + } } /* Set up faces after all frame parameters are known. This call @@ -5146,7 +5083,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo, call2 (Qface_set_after_frame_default, frame, Qnil); if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) - Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg))); + { + AUTO_FRAME_ARG (arg, Qbackground_color, bg); + Fmodify_frame_parameters (frame, arg); + } } f->no_split = 1; @@ -5162,7 +5102,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, below. And the frame needs to be on Vframe_list or making it visible won't work. */ Vframe_list = Fcons (frame, Vframe_list); - + f->official = true; /* Setting attributes of faces of the tooltip frame from resources and similar will increment face_change_count, which leads to the @@ -5668,7 +5608,11 @@ or directory must exist. This function is only defined on NS, MS Windows, and X Windows with the Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. -Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) +Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. +On Windows 7 and later, the file selection dialog "remembers" the last +directory where the user selected a file, and will open that directory +instead of DIR on subsequent invocations of this function with the same +value of DIR as in previous invocations; this is standard Windows behavior. */) (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) { @@ -5840,7 +5784,11 @@ or directory must exist. This function is only defined on NS, MS Windows, and X Windows with the Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. -Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) +Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. +On Windows 7 and later, the file selection dialog "remembers" the last +directory where the user selected a file, and will open that directory +instead of DIR on subsequent invocations of this function with the same +value of DIR as in previous invocations; this is standard Windows behavior. */) (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) { struct frame *f = SELECTED_FRAME (); @@ -6038,7 +5986,11 @@ present and mapped to the usual X keysyms. */) XkbFreeNames (kb, 0, True); } - XkbFreeClientMap (kb, 0, True); + /* As of libX11-1.6.2, XkbGetMap manual says that you should use + XkbFreeClientMap to free the data returned by XkbGetMap. But + this function just frees the data referenced from KB and not + KB itself. To free KB as well, call XkbFreeKeyboard. */ + XkbFreeKeyboard (kb, XkbAllMapComponentsMask, True); if (delete_keycode && backspace_keycode @@ -6080,17 +6032,19 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_mouse_color, x_explicitly_set_name, x_set_scroll_bar_width, + x_set_scroll_bar_height, x_set_title, x_set_unsplittable, x_set_vertical_scroll_bars, + x_set_horizontal_scroll_bars, x_set_visibility, x_set_tool_bar_lines, x_set_scroll_bar_foreground, x_set_scroll_bar_background, x_set_screen_gamma, x_set_line_spacing, - x_set_fringe_width, - x_set_fringe_width, + x_set_left_fringe, + x_set_right_fringe, x_set_wait_for_wm, x_set_fullscreen, x_set_font_backend, @@ -6102,15 +6056,10 @@ frame_parm_handler x_frame_parm_handlers[] = void syms_of_xfns (void) { - /* The section below is built by the lisp expression at the top of the file, - just above where these variables are declared. */ - /*&&& init symbols here &&&*/ - DEFSYM (Qsuppress_icon, "suppress-icon"); DEFSYM (Qundefined_color, "undefined-color"); DEFSYM (Qcompound_text, "compound-text"); DEFSYM (Qcancel_timer, "cancel-timer"); DEFSYM (Qfont_param, "font-parameter"); - /* This is the end of symbol initialization. */ Fput (Qundefined_color, Qerror_conditions, listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));