X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/2538fae4f8e5e7a82449dd904d471439c9eb6345..7c402969951c97a2d878c16f7f4c18152258e1f9:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 714aaad9d7..934c11d98b 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1,5 +1,6 @@ /* Generic frame functions. - Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000 Free Software Foundation. + Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2003 + Free Software Foundation. This file is part of GNU Emacs. @@ -29,6 +30,9 @@ Boston, MA 02111-1307, USA. */ #ifdef WINDOWSNT #include "w32term.h" #endif +#ifdef MAC_OS +#include "macterm.h" +#endif #include "buffer.h" /* These help us bind and responding to switch-frame events. */ #include "commands.h" @@ -37,6 +41,7 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_WINDOW_SYSTEM #include "fontset.h" #endif +#include "blockinput.h" #include "termhooks.h" #include "dispextern.h" #include "window.h" @@ -45,128 +50,74 @@ Boston, MA 02111-1307, USA. */ #include "dosfns.h" #endif -#ifdef macintosh -extern struct mac_output *NewMacWindow (); -extern void DisposeMacWindow (struct mac_output *); + +#ifdef HAVE_WINDOW_SYSTEM + +/* The name we're using in resource queries. Most often "emacs". */ + +Lisp_Object Vx_resource_name; + +/* The application class we're using in resource queries. + Normally "Emacs". */ + +Lisp_Object Vx_resource_class; + #endif -/* Evaluate this expression to rebuild the section of syms_of_frame - that initializes and staticpros the symbols declared below. Note - that Emacs 18 has a bug that keeps C-x C-e from being able to - evaluate this expression. - -(progn - ;; Accumulate a list of the symbols we want to initialize from the - ;; declarations at the top of the file. - (goto-char (point-min)) - (search-forward "/\*&&& symbols declared here &&&*\/\n") - (let (symbol-list) - (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)") - (setq symbol-list - (cons (buffer-substring (match-beginning 1) (match-end 1)) - symbol-list)) - (forward-line 1)) - (setq symbol-list (nreverse symbol-list)) - ;; Delete the section of syms_of_... where we initialize the symbols. - (search-forward "\n /\*&&& init symbols here &&&*\/\n") - (let ((start (point))) - (while (looking-at "^ Q") - (forward-line 2)) - (kill-region start (point))) - ;; Write a new symbol initialization section. - (while symbol-list - (insert (format " %s = intern (\"" (car symbol-list))) - (let ((start (point))) - (insert (substring (car symbol-list) 1)) - (subst-char-in-region start (point) ?_ ?-)) - (insert (format "\");\n staticpro (&%s);\n" (car symbol-list))) - (setq symbol-list (cdr symbol-list))))) - */ - -/*&&& symbols declared here &&&*/ -Lisp_Object Qframep; -Lisp_Object Qframe_live_p; -Lisp_Object Qheight; -Lisp_Object Qicon; -Lisp_Object Qminibuffer; -Lisp_Object Qmodeline; -Lisp_Object Qname; +Lisp_Object Qframep, Qframe_live_p; +Lisp_Object Qicon, Qmodeline; Lisp_Object Qonly; -Lisp_Object Qunsplittable; -Lisp_Object Qmenu_bar_lines; -Lisp_Object Qtool_bar_lines; -Lisp_Object Qwidth; -Lisp_Object Qx; -Lisp_Object Qw32; -Lisp_Object Qpc; -Lisp_Object Qmac; +Lisp_Object Qx, Qw32, Qmac, Qpc; Lisp_Object Qvisible; -Lisp_Object Qbuffer_predicate; -Lisp_Object Qbuffer_list; -Lisp_Object Qtitle; +Lisp_Object Qdisplay_type; +Lisp_Object Qbackground_mode; +Lisp_Object Qinhibit_default_face_x_resources; + +Lisp_Object Qx_frame_parameter; +Lisp_Object Qx_resource_name; + +/* Frame parameters (set or reported). */ + +Lisp_Object Qauto_raise, Qauto_lower; +Lisp_Object Qborder_color, Qborder_width; +Lisp_Object Qcursor_color, Qcursor_type; +Lisp_Object Qgeometry; /* Not used */ +Lisp_Object Qheight, Qwidth; +Lisp_Object Qleft, Qright; +Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; +Lisp_Object Qinternal_border_width; +Lisp_Object Qmouse_color; +Lisp_Object Qminibuffer; +Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; +Lisp_Object Qvisibility; +Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; +Lisp_Object Qscreen_gamma; +Lisp_Object Qline_spacing; +Lisp_Object Quser_position, Quser_size; +Lisp_Object Qwait_for_wm; +Lisp_Object Qwindow_id; +#ifdef HAVE_X_WINDOWS +Lisp_Object Qouter_window_id; +#endif +Lisp_Object Qparent_id; +Lisp_Object Qtitle, Qname; +Lisp_Object Qunsplittable; +Lisp_Object Qmenu_bar_lines, Qtool_bar_lines; +Lisp_Object Qleft_fringe, Qright_fringe; +Lisp_Object Qbuffer_predicate, Qbuffer_list; +Lisp_Object Qtty_color_mode; + +Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth; + +Lisp_Object Qface_set_after_frame_default; + Lisp_Object Vterminal_frame; Lisp_Object Vdefault_frame_alist; +Lisp_Object Vdefault_frame_scroll_bars; Lisp_Object Vmouse_position_function; - -static void -syms_of_frame_1 () -{ - /*&&& init symbols here &&&*/ - Qframep = intern ("framep"); - staticpro (&Qframep); - Qframe_live_p = intern ("frame-live-p"); - staticpro (&Qframe_live_p); - Qheight = intern ("height"); - staticpro (&Qheight); - Qicon = intern ("icon"); - staticpro (&Qicon); - Qminibuffer = intern ("minibuffer"); - staticpro (&Qminibuffer); - Qmodeline = intern ("modeline"); - staticpro (&Qmodeline); - Qname = intern ("name"); - staticpro (&Qname); - Qonly = intern ("only"); - staticpro (&Qonly); - Qunsplittable = intern ("unsplittable"); - staticpro (&Qunsplittable); - Qmenu_bar_lines = intern ("menu-bar-lines"); - staticpro (&Qmenu_bar_lines); - Qtool_bar_lines = intern ("tool-bar-lines"); - staticpro (&Qtool_bar_lines); - Qwidth = intern ("width"); - staticpro (&Qwidth); - Qx = intern ("x"); - staticpro (&Qx); - Qw32 = intern ("w32"); - staticpro (&Qw32); - Qpc = intern ("pc"); - staticpro (&Qpc); - Qmac = intern ("mac"); - staticpro (&Qmac); - Qvisible = intern ("visible"); - staticpro (&Qvisible); - Qbuffer_predicate = intern ("buffer-predicate"); - staticpro (&Qbuffer_predicate); - Qbuffer_list = intern ("buffer-list"); - staticpro (&Qbuffer_list); - Qtitle = intern ("title"); - staticpro (&Qtitle); - - DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist, - "Alist of default values for frame creation.\n\ -These may be set in your init file, like this:\n\ - (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\ -These override values given in window system configuration data,\n\ - including X Windows' defaults database.\n\ -For values specific to the first Emacs frame, see `initial-frame-alist'.\n\ -For values specific to the separate minibuffer frame, see\n\ - `minibuffer-frame-alist'.\n\ -The `menu-bar-lines' element of the list controls whether new frames\n\ - have menu bars; `menu-bar-mode' works by altering this element."); - Vdefault_frame_alist = Qnil; -} +Lisp_Object Vmouse_highlight; +Lisp_Object Vdelete_frame_functions; static void set_menu_bar_lines_1 (window, n) @@ -176,13 +127,13 @@ set_menu_bar_lines_1 (window, n) struct window *w = XWINDOW (window); XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->top, XFASTINT (w->top) + n); - XSETFASTINT (w->height, XFASTINT (w->height) - n); - - if (INTEGERP (w->orig_top)) - XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n); - if (INTEGERP (w->orig_height)) - XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n); + XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); + XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); + + if (INTEGERP (w->orig_top_line)) + XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n); + if (INTEGERP (w->orig_total_lines)) + XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n); /* Handle just the top child in a vertical split. */ if (!NILP (w->vchild)) @@ -238,14 +189,14 @@ extern Lisp_Object Fredirect_frame_focus (); extern Lisp_Object x_get_focus_frame (); DEFUN ("framep", Fframep, Sframep, 1, 1, 0, - "Return non-nil if OBJECT is a frame.\n\ -Value is t for a termcap frame (a character-only terminal),\n\ -`x' for an Emacs frame that is really an X window,\n\ -`w32' for an Emacs frame that is a window on MS-Windows display,\n\ -`mac' for an Emacs frame on a Macintosh display,\n\ -`pc' for a direct-write MS-DOS frame.\n\ -See also `frame-live-p'.") - (object) + doc: /* Return non-nil if OBJECT is a frame. +Value is t for a termcap frame (a character-only terminal), +`x' for an Emacs frame that is really an X window, +`w32' for an Emacs frame that is a window on MS-Windows display, +`mac' for an Emacs frame on a Macintosh display, +`pc' for a direct-write MS-DOS frame. +See also `frame-live-p'. */) + (object) Lisp_Object object; { if (!FRAMEP (object)) @@ -268,12 +219,12 @@ See also `frame-live-p'.") } DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0, - "Return non-nil if OBJECT is a frame which has not been deleted.\n\ -Value is nil if OBJECT is not a live frame. If object is a live\n\ -frame, the return value indicates what sort of output device it is\n\ -displayed on. Value is t for a termcap frame (a character-only\n\ -terminal), `x' for an Emacs frame being displayed in an X window.") - (object) + doc: /* Return non-nil if OBJECT is a frame which has not been deleted. +Value is nil if OBJECT is not a live frame. If object is a live +frame, the return value indicates what sort of output device it is +displayed on. See the documentation of `framep' for possible +return values. */) + (object) Lisp_Object object; { return ((FRAMEP (object) @@ -290,14 +241,8 @@ make_frame (mini_p) register struct frame *f; register Lisp_Object root_window; register Lisp_Object mini_window; - register struct Lisp_Vector *vec; - int i; - vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame)); - for (i = 0; i < VECSIZE (struct frame); i++) - XSETFASTINT (vec->contents[i], 0); - vec->size = VECSIZE (struct frame); - f = (struct frame *)vec; + f = allocate_frame (); XSETFRAME (frame, f); f->desired_matrix = 0; @@ -338,9 +283,22 @@ make_frame (mini_p) f->title = Qnil; f->menu_bar_window = Qnil; f->tool_bar_window = Qnil; - f->desired_tool_bar_items = f->current_tool_bar_items = Qnil; + f->tool_bar_items = Qnil; f->desired_tool_bar_string = f->current_tool_bar_string = Qnil; - f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0; + f->n_tool_bar_items = 0; + f->left_fringe_width = f->right_fringe_width = 0; + f->fringe_cols = 0; + f->scroll_bar_actual_width = 0; + f->border_width = 0; + f->internal_border_width = 0; + f->column_width = 1; /* !FRAME_WINDOW_P value */ + f->line_height = 1; /* !FRAME_WINDOW_P value */ + f->x_pixels_diff = f->y_pixels_diff = 0; +#ifdef HAVE_WINDOW_SYSTEM + f->want_fullscreen = FULLSCREEN_NONE; +#endif + f->size_hint_flags = 0; + f->win_gravity = 0; root_window = make_window (); if (mini_p) @@ -365,17 +323,17 @@ make_frame (mini_p) just so that there is "something there." Correct size will be set up later with change_frame_size. */ - SET_FRAME_WIDTH (f, 10); - f->height = 10; + SET_FRAME_COLS (f, 10); + FRAME_LINES (f) = 10; - XSETFASTINT (XWINDOW (root_window)->width, 10); - XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10)); + XSETFASTINT (XWINDOW (root_window)->total_cols, 10); + XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10)); if (mini_p) { - XSETFASTINT (XWINDOW (mini_window)->width, 10); - XSETFASTINT (XWINDOW (mini_window)->top, 9); - XSETFASTINT (XWINDOW (mini_window)->height, 1); + XSETFASTINT (XWINDOW (mini_window)->total_cols, 10); + XSETFASTINT (XWINDOW (mini_window)->top_line, 9); + XSETFASTINT (XWINDOW (mini_window)->total_lines, 1); } /* Choose a buffer for the frame's root window. */ @@ -386,7 +344,7 @@ make_frame (mini_p) buf = Fcurrent_buffer (); /* If buf is a 'hidden' buffer (i.e. one whose name starts with a space), try to find another one. */ - if (XSTRING (Fbuffer_name (buf))->data[0] == ' ') + if (SREF (Fbuffer_name (buf), 0) == ' ') buf = Fother_buffer (buf, Qnil, Qnil); /* Use set_window_buffer, not Fset_window_buffer, and don't let @@ -395,7 +353,7 @@ make_frame (mini_p) don't have the right size, glyph matrices aren't initialized etc. Running Lisp functions at this point surely ends in a SEGV. */ - set_window_buffer (root_window, buf, 0); + set_window_buffer (root_window, buf, 0, 0); f->buffer_list = Fcons (buf, Qnil); } @@ -406,7 +364,7 @@ make_frame (mini_p) (NILP (Vminibuffer_list) ? get_minibuffer (0) : Fcar (Vminibuffer_list)), - 0); + 0, 0); } f->root_window = root_window; @@ -415,6 +373,8 @@ make_frame (mini_p) a newly-created, never-selected window. */ XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count); + f->default_face_done_p = 0; + return f; } @@ -433,7 +393,7 @@ make_frame_without_minibuffer (mini_window, kb, display) struct gcpro gcpro1; if (!NILP (mini_window)) - CHECK_LIVE_WINDOW (mini_window, 0); + CHECK_LIVE_WINDOW (mini_window); #ifdef MULTI_KBOARD if (!NILP (mini_window) @@ -459,7 +419,7 @@ make_frame_without_minibuffer (mini_window, kb, display) call1 (intern ("make-initial-minibuffer-frame"), display); UNGCPRO; } - + mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window; } @@ -471,7 +431,7 @@ make_frame_without_minibuffer (mini_window, kb, display) Fset_window_buffer (mini_window, (NILP (Vminibuffer_list) ? get_minibuffer (0) - : Fcar (Vminibuffer_list))); + : Fcar (Vminibuffer_list)), Qnil); return f; } @@ -509,7 +469,7 @@ make_minibuffer_frame () Fset_window_buffer (mini_window, (NILP (Vminibuffer_list) ? get_minibuffer (0) - : Fcar (Vminibuffer_list))); + : Fcar (Vminibuffer_list)), Qnil); return f; } #endif /* HAVE_WINDOW_SYSTEM */ @@ -555,41 +515,57 @@ make_terminal_frame () if (!inhibit_window_system && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)) || XFRAME (selected_frame)->output_method == output_msdos_raw)) - f->output_method = output_msdos_raw; + { + f->output_method = output_msdos_raw; + /* This initialization of foreground and background pixels is + only important for the initial frame created in temacs. If + we don't do that, we get black background and foreground in + the dumped Emacs because the_only_x_display is a static + variable, hence it is born all-zeroes, and zero is the code + for the black color. Other frames all inherit their pixels + from what's already in the_only_x_display. */ + if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))) + && f->output_data.x->background_pixel == 0 + && f->output_data.x->foreground_pixel == 0) + { + f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR; + f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR; + } + } else f->output_method = output_termcap; #else -#ifdef macintosh - f->output_data.mac = NewMacWindow(f); - f->output_data.mac->background_pixel = 0xffffff; - f->output_data.mac->foreground_pixel = 0; - f->output_data.mac->n_param_faces = 0; - f->output_data.mac->n_computed_faces = 0; - f->output_data.mac->size_computed_faces = 0; - f->output_method = output_mac; - f->auto_raise = 1; - f->auto_lower = 1; - init_frame_faces (f); -#else /* !macintosh */ +#ifdef WINDOWSNT + f->output_method = output_termcap; + f->output_data.x = &tty_display; +#else +#ifdef MAC_OS8 + make_mac_terminal_frame (f); +#else f->output_data.x = &tty_display; -#endif /* !macintosh */ +#ifdef CANNOT_DUMP + FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR; + FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR; +#endif +#endif /* MAC_OS8 */ +#endif /* WINDOWSNT */ #endif /* MSDOS */ -#ifndef macintosh if (!noninteractive) init_frame_faces (f); -#endif + return f; } DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, - 1, 1, 0, "Create an additional terminal frame.\n\ -You can create multiple frames on a text-only terminal in this way.\n\ -Only the selected terminal frame is actually displayed.\n\ -This function takes one argument, an alist specifying frame parameters.\n\ -In practice, generally you don't need to specify any parameters.\n\ -Note that changing the size of one terminal frame automatically affects all.") - (parms) + 1, 1, 0, + doc: /* Create an additional terminal frame. +You can create multiple frames on a text-only terminal in this way. +Only the selected terminal frame is actually displayed. +This function takes one argument, an alist specifying frame parameters. +In practice, generally you don't need to specify any parameters. +Note that changing the size of one terminal frame automatically affects all. */) + (parms) Lisp_Object parms; { struct frame *f; @@ -602,7 +578,7 @@ Note that changing the size of one terminal frame automatically affects all.") abort (); #else /* not MSDOS */ -#ifdef macintosh +#ifdef MAC_OS if (sf->output_method != output_mac) error ("Not running on a Macintosh screen; cannot make a new Macintosh frame"); #else @@ -613,8 +589,8 @@ Note that changing the size of one terminal frame automatically affects all.") f = make_terminal_frame (); - change_frame_size (f, FRAME_HEIGHT (sf), - FRAME_WIDTH (sf), 0, 0, 0); + change_frame_size (f, FRAME_LINES (sf), + FRAME_COLS (sf), 0, 0, 0); adjust_glyphs (f); calculate_costs (f); XSETFRAME (frame, f); @@ -628,17 +604,31 @@ Note that changing the size of one terminal frame automatically affects all.") the vectors which are the CDRs of associations in face_alist to be copied as well. */ for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem)) - XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem))); + XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem)))); return frame; } + +/* Perform the switch to frame FRAME. + + If FRAME is a switch-frame event `(switch-frame FRAME1)', use + FRAME1 as frame. + + If TRACK is non-zero and the frame that currently has the focus + redirects its focus to the selected frame, redirect that focused + frame's focus to FRAME instead. + + FOR_DELETION non-zero means that the selected frame is being + deleted, which includes the possibility that the frame's display + is dead. */ + Lisp_Object -do_switch_frame (frame, no_enter, track) - Lisp_Object frame, no_enter; - int track; +do_switch_frame (frame, track, for_deletion) + Lisp_Object frame; + int track, for_deletion; { struct frame *sf = SELECTED_FRAME (); - + /* If FRAME is a switch-frame event, extract the frame we should switch to. */ if (CONSP (frame) @@ -649,7 +639,7 @@ do_switch_frame (frame, no_enter, track) /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for a switch-frame event to arrive after a frame is no longer live, especially when deleting the initial frame during startup. */ - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); if (! FRAME_LIVE_P (XFRAME (frame))) return Qnil; @@ -686,7 +676,7 @@ do_switch_frame (frame, no_enter, track) #else /* ! 0 */ /* Instead, apply it only to the frame we're pointing to. */ #ifdef HAVE_WINDOW_SYSTEM - if (track && (FRAME_WINDOW_P (XFRAME (frame)))) + if (track && FRAME_WINDOW_P (XFRAME (frame))) { Lisp_Object focus, xfocus; @@ -701,11 +691,31 @@ do_switch_frame (frame, no_enter, track) #endif /* HAVE_X_WINDOWS */ #endif /* ! 0 */ + if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) + resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); + selected_frame = frame; if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) last_nonminibuf_frame = XFRAME (selected_frame); - Fselect_window (XFRAME (frame)->selected_window); + Fselect_window (XFRAME (frame)->selected_window, Qnil); + +#ifndef WINDOWSNT + /* Make sure to switch the tty color mode to that of the newly + selected frame. */ + sf = SELECTED_FRAME (); + if (FRAME_TERMCAP_P (sf)) + { + Lisp_Object color_mode_spec, color_mode; + + color_mode_spec = assq_no_quit (Qtty_color_mode, sf->param_alist); + if (CONSP (color_mode_spec)) + color_mode = XCDR (color_mode_spec); + else + color_mode = make_number (0); + set_tty_color_mode (sf, color_mode); + } +#endif /* !WINDOWSNT */ /* We want to make sure that the next event generates a frame-switch event to the appropriate frame. This seems kludgy to me, but @@ -719,39 +729,39 @@ do_switch_frame (frame, no_enter, track) } DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e", - "Select the frame FRAME.\n\ -Subsequent editing commands apply to its selected window.\n\ -The selection of FRAME lasts until the next time the user does\n\ -something to select a different frame, or until the next time this\n\ -function is called.") + doc: /* Select the frame FRAME. +Subsequent editing commands apply to its selected window. +The selection of FRAME lasts until the next time the user does +something to select a different frame, or until the next time this +function is called. */) (frame, no_enter) Lisp_Object frame, no_enter; { - return do_switch_frame (frame, no_enter, 1); + return do_switch_frame (frame, 1, 0); } DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e", - "Handle a switch-frame event EVENT.\n\ -Switch-frame events are usually bound to this function.\n\ -A switch-frame event tells Emacs that the window manager has requested\n\ -that the user's events be directed to the frame mentioned in the event.\n\ -This function selects the selected window of the frame of EVENT.\n\ -\n\ -If EVENT is frame object, handle it as if it were a switch-frame event\n\ -to that frame.") - (event, no_enter) + doc: /* Handle a switch-frame event EVENT. +Switch-frame events are usually bound to this function. +A switch-frame event tells Emacs that the window manager has requested +that the user's events be directed to the frame mentioned in the event. +This function selects the selected window of the frame of EVENT. + +If EVENT is frame object, handle it as if it were a switch-frame event +to that frame. */) + (event, no_enter) Lisp_Object event, no_enter; { /* Preserve prefix arg that the command loop just cleared. */ current_kboard->Vprefix_arg = Vcurrent_prefix_arg; call1 (Vrun_hooks, Qmouse_leave_buffer_hook); - return do_switch_frame (event, no_enter, 0); + return do_switch_frame (event, 0, 0); } DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "", - "Do nothing, but preserve any prefix argument already specified.\n\ -This is a suitable binding for iconify-frame and make-frame-visible.") + doc: /* Do nothing, but preserve any prefix argument already specified. +This is a suitable binding for `iconify-frame' and `make-frame-visible'. */) () { current_kboard->Vprefix_arg = Vcurrent_prefix_arg; @@ -759,25 +769,25 @@ This is a suitable binding for iconify-frame and make-frame-visible.") } DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, - "Return the frame that is now selected.") - () + doc: /* Return the frame that is now selected. */) + () { return selected_frame; } DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, - "Return the frame object that window WINDOW is on.") - (window) + doc: /* Return the frame object that window WINDOW is on. */) + (window) Lisp_Object window; { - CHECK_LIVE_WINDOW (window, 0); + CHECK_LIVE_WINDOW (window); return XWINDOW (window)->frame; } DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0, - "Returns the topmost, leftmost window of FRAME.\n\ -If omitted, FRAME defaults to the currently selected frame.") - (frame) + doc: /* Returns the topmost, leftmost window of FRAME. +If omitted, FRAME defaults to the currently selected frame. */) + (frame) Lisp_Object frame; { Lisp_Object w; @@ -786,7 +796,7 @@ If omitted, FRAME defaults to the currently selected frame.") w = SELECTED_FRAME ()->root_window; else { - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); w = XFRAME (frame)->root_window; } while (NILP (XWINDOW (w)->buffer)) @@ -803,45 +813,45 @@ If omitted, FRAME defaults to the currently selected frame.") DEFUN ("active-minibuffer-window", Factive_minibuffer_window, Sactive_minibuffer_window, 0, 0, 0, - "Return the currently active minibuffer window, or nil if none.") - () + doc: /* Return the currently active minibuffer window, or nil if none. */) + () { return minibuf_level ? minibuf_window : Qnil; } DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0, - "Returns the root-window of FRAME.\n\ -If omitted, FRAME defaults to the currently selected frame.") - (frame) + doc: /* Returns the root-window of FRAME. +If omitted, FRAME defaults to the currently selected frame. */) + (frame) Lisp_Object frame; { Lisp_Object window; - + if (NILP (frame)) window = SELECTED_FRAME ()->root_window; else { - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); window = XFRAME (frame)->root_window; } - + return window; } DEFUN ("frame-selected-window", Fframe_selected_window, Sframe_selected_window, 0, 1, 0, - "Return the selected window of frame object FRAME.\n\ -If omitted, FRAME defaults to the currently selected frame.") - (frame) + doc: /* Return the selected window of frame object FRAME. +If omitted, FRAME defaults to the currently selected frame. */) + (frame) Lisp_Object frame; { Lisp_Object window; - + if (NILP (frame)) window = SELECTED_FRAME ()->selected_window; else { - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); window = XFRAME (frame)->selected_window; } @@ -850,33 +860,39 @@ If omitted, FRAME defaults to the currently selected frame.") DEFUN ("set-frame-selected-window", Fset_frame_selected_window, Sset_frame_selected_window, 2, 2, 0, - "Set the selected window of frame object FRAME to WINDOW.\n\ -If FRAME is nil, the selected frame is used.\n\ -If FRAME is the selected frame, this makes WINDOW the selected window.") - (frame, window) + doc: /* Set the selected window of frame object FRAME to WINDOW. +If FRAME is nil, the selected frame is used. +If FRAME is the selected frame, this makes WINDOW the selected window. */) + (frame, window) Lisp_Object frame, window; { if (NILP (frame)) frame = selected_frame; - - CHECK_LIVE_FRAME (frame, 0); - CHECK_LIVE_WINDOW (window, 1); + + CHECK_LIVE_FRAME (frame); + CHECK_LIVE_WINDOW (window); if (! EQ (frame, WINDOW_FRAME (XWINDOW (window)))) error ("In `set-frame-selected-window', WINDOW is not on FRAME"); if (EQ (frame, selected_frame)) - return Fselect_window (window); + return Fselect_window (window, Qnil); return XFRAME (frame)->selected_window = window; } DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0, - "Return a list of all frames.") - () + doc: /* Return a list of all frames. */) + () { - return Fcopy_sequence (Vframe_list); + Lisp_Object frames; + frames = Fcopy_sequence (Vframe_list); +#ifdef HAVE_WINDOW_SYSTEM + if (FRAMEP (tip_frame)) + frames = Fdelq (tip_frame, frames); +#endif + return frames; } /* Return the next frame in the frame list after FRAME. @@ -901,7 +917,7 @@ next_frame (frame, minibuf) /* If this frame is dead, it won't be in Vframe_list, and we'll loop forever. Forestall that. */ - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); while (1) for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) @@ -1037,43 +1053,43 @@ prev_frame (frame, minibuf) DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0, - "Return the next frame in the frame list after FRAME.\n\ -It considers only frames on the same terminal as FRAME.\n\ -By default, skip minibuffer-only frames.\n\ -If omitted, FRAME defaults to the selected frame.\n\ -If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\ -If MINIFRAME is a window, include only its own frame\n\ -and any frame now using that window as the minibuffer.\n\ -If MINIFRAME is `visible', include all visible frames.\n\ -If MINIFRAME is 0, include all visible and iconified frames.\n\ -Otherwise, include all frames.") - (frame, miniframe) + doc: /* Return the next frame in the frame list after FRAME. +It considers only frames on the same terminal as FRAME. +By default, skip minibuffer-only frames. +If omitted, FRAME defaults to the selected frame. +If optional argument MINIFRAME is nil, exclude minibuffer-only frames. +If MINIFRAME is a window, include only its own frame +and any frame now using that window as the minibuffer. +If MINIFRAME is `visible', include all visible frames. +If MINIFRAME is 0, include all visible and iconified frames. +Otherwise, include all frames. */) + (frame, miniframe) Lisp_Object frame, miniframe; { if (NILP (frame)) frame = selected_frame; - - CHECK_LIVE_FRAME (frame, 0); + + CHECK_LIVE_FRAME (frame); return next_frame (frame, miniframe); } DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0, - "Return the previous frame in the frame list before FRAME.\n\ -It considers only frames on the same terminal as FRAME.\n\ -By default, skip minibuffer-only frames.\n\ -If omitted, FRAME defaults to the selected frame.\n\ -If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\ -If MINIFRAME is a window, include only its own frame\n\ -and any frame now using that window as the minibuffer.\n\ -If MINIFRAME is `visible', include all visible frames.\n\ -If MINIFRAME is 0, include all visible and iconified frames.\n\ -Otherwise, include all frames.") - (frame, miniframe) + doc: /* Return the previous frame in the frame list before FRAME. +It considers only frames on the same terminal as FRAME. +By default, skip minibuffer-only frames. +If omitted, FRAME defaults to the selected frame. +If optional argument MINIFRAME is nil, exclude minibuffer-only frames. +If MINIFRAME is a window, include only its own frame +and any frame now using that window as the minibuffer. +If MINIFRAME is `visible', include all visible frames. +If MINIFRAME is 0, include all visible and iconified frames. +Otherwise, include all frames. */) + (frame, miniframe) Lisp_Object frame, miniframe; { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); return prev_frame (frame, miniframe); } @@ -1123,12 +1139,16 @@ other_visible_frames (f) } DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "", - "Delete FRAME, permanently eliminating it from use.\n\ -If omitted, FRAME defaults to the selected frame.\n\ -A frame may not be deleted if its minibuffer is used by other frames.\n\ -Normally, you may not delete a frame if all other frames are invisible,\n\ -but if the second optional argument FORCE is non-nil, you may do so.") - (frame, force) + doc: /* Delete FRAME, permanently eliminating it from use. +If omitted, FRAME defaults to the selected frame. +A frame may not be deleted if its minibuffer is used by other frames. +Normally, you may not delete a frame if all other frames are invisible, +but if the second optional argument FORCE is non-nil, you may do so. + +This function runs `delete-frame-functions' before actually deleting the +frame, unless the frame is a tooltip. +The functions are run with one arg, the frame to be deleted. */) + (frame, force) Lisp_Object frame, force; { struct frame *f; @@ -1142,14 +1162,20 @@ but if the second optional argument FORCE is non-nil, you may do so.") } else { - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); } if (! FRAME_LIVE_P (f)) return Qnil; - if (NILP (force) && !other_visible_frames (f)) + if (NILP (force) && !other_visible_frames (f) +#ifdef MAC_OS8 + /* Terminal frame deleted before any other visible frames are + created. */ + && strcmp (SDATA (f->name), "F1") != 0 +#endif + ) error ("Attempt to delete the sole visible or iconified frame"); #if 0 @@ -1180,6 +1206,16 @@ but if the second optional argument FORCE is non-nil, you may do so.") } } + /* Run `delete-frame-functions' unless frame is a tooltip. */ + if (!NILP (Vrun_hooks) + && NILP (Fframe_parameter (frame, intern ("tooltip")))) + { + Lisp_Object args[2]; + args[0] = intern ("delete-frame-functions"); + args[1] = frame; + Frun_hook_with_args (2, args); + } + minibuffer_selected = EQ (minibuf_window, selected_window); /* Don't let the frame remain selected. */ @@ -1200,7 +1236,7 @@ but if the second optional argument FORCE is non-nil, you may do so.") } } - do_switch_frame (frame1, Qnil, 0); + do_switch_frame (frame1, 0, 1); sf = SELECTED_FRAME (); } @@ -1208,13 +1244,13 @@ but if the second optional argument FORCE is non-nil, you may do so.") if (EQ (f->minibuffer_window, minibuf_window)) { Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qnil); minibuf_window = sf->minibuffer_window; /* If the dying minibuffer window was selected, select the new one. */ if (minibuffer_selected) - Fselect_window (minibuf_window); + Fselect_window (minibuf_window, Qnil); } /* Don't let echo_area_window to remain on a deleted frame. */ @@ -1227,8 +1263,8 @@ but if the second optional argument FORCE is non-nil, you may do so.") x_clear_frame_selections (f); #endif - /* Free glyphs. - This function must be called before the window tree of the + /* Free glyphs. + This function must be called before the window tree of the frame is deleted because windows contain dynamically allocated memory. */ free_glyphs (f); @@ -1243,6 +1279,8 @@ but if the second optional argument FORCE is non-nil, you may do so.") if (f->namebuf) xfree (f->namebuf); + if (f->decode_mode_spec_buffer) + xfree (f->decode_mode_spec_buffer); if (FRAME_INSERT_COST (f)) xfree (FRAME_INSERT_COST (f)); if (FRAME_DELETEN_COST (f)) @@ -1266,14 +1304,6 @@ but if the second optional argument FORCE is non-nil, you may do so.") x_destroy_window (f); #endif -/* Done by x_destroy_window above already */ -#if 0 -#ifdef macintosh - if (FRAME_MAC_P (f)) - DisposeMacWindow (f->output_data.mac); -#endif -#endif - f->output_data.nothing = 0; /* If we've deleted the last_nonminibuf_frame, then try to find @@ -1365,15 +1395,16 @@ but if the second optional argument FORCE is non-nil, you may do so.") /* Return mouse position in character cell units. */ DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, - "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\ -The position is given in character cells, where (0, 0) is the\n\ -upper-left corner.\n\ -If Emacs is running on a mouseless terminal or hasn't been programmed\n\ -to read the mouse position, it returns the selected frame for FRAME\n\ -and nil for X and Y.\n\ -Runs the abnormal hook `mouse-position-function' with the normal return\n\ -value as argument.") - () + doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position. +The position is given in character cells, where (0, 0) is the +upper-left corner. +If Emacs is running on a mouseless terminal or hasn't been programmed +to read the mouse position, it returns the selected frame for FRAME +and nil for X and Y. +If `mouse-position-function' is non-nil, `mouse-position' calls it, +passing the normal return value to that function as an argument, +and returns whatever that function returns. */) + () { FRAME_PTR f; Lisp_Object lispy_dummy; @@ -1412,13 +1443,13 @@ value as argument.") DEFUN ("mouse-pixel-position", Fmouse_pixel_position, Smouse_pixel_position, 0, 0, 0, - "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\ -The position is given in pixel units, where (0, 0) is the\n\ -upper-left corner.\n\ -If Emacs is running on a mouseless terminal or hasn't been programmed\n\ -to read the mouse position, it returns the selected frame for FRAME\n\ -and nil for X and Y.") - () + doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position. +The position is given in pixel units, where (0, 0) is the +upper-left corner. +If Emacs is running on a mouseless terminal or hasn't been programmed +to read the mouse position, it returns the selected frame for FRAME +and nil for X and Y. */) + () { FRAME_PTR f; Lisp_Object lispy_dummy; @@ -1442,26 +1473,26 @@ and nil for X and Y.") } DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0, - "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\ -Coordinates are relative to the frame, not a window,\n\ -so the coordinates of the top left character in the frame\n\ -may be nonzero due to left-hand scroll bars or the menu bar.\n\ -\n\ -This function is a no-op for an X frame that is not visible.\n\ -If you have just created a frame, you must wait for it to become visible\n\ -before calling this function on it, like this.\n\ - (while (not (frame-visible-p frame)) (sleep-for .5))") + doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME. +Coordinates are relative to the frame, not a window, +so the coordinates of the top left character in the frame +may be nonzero due to left-hand scroll bars or the menu bar. + +This function is a no-op for an X frame that is not visible. +If you have just created a frame, you must wait for it to become visible +before calling this function on it, like this. + (while (not (frame-visible-p frame)) (sleep-for .5)) */) (frame, x, y) Lisp_Object frame, x, y; { - CHECK_LIVE_FRAME (frame, 0); - CHECK_NUMBER (x, 2); - CHECK_NUMBER (y, 1); + CHECK_LIVE_FRAME (frame); + CHECK_NUMBER (x); + CHECK_NUMBER (y); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) - /* Warping the mouse will cause enternotify and focus events. */ + /* Warping the mouse will cause enternotify and focus events. */ x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y)); #else #if defined (MSDOS) && defined (HAVE_MOUSE) @@ -1478,22 +1509,22 @@ before calling this function on it, like this.\n\ DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position, Sset_mouse_pixel_position, 3, 3, 0, - "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\ -Note, this is a no-op for an X frame that is not visible.\n\ -If you have just created a frame, you must wait for it to become visible\n\ -before calling this function on it, like this.\n\ - (while (not (frame-visible-p frame)) (sleep-for .5))") + doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME. +Note, this is a no-op for an X frame that is not visible. +If you have just created a frame, you must wait for it to become visible +before calling this function on it, like this. + (while (not (frame-visible-p frame)) (sleep-for .5)) */) (frame, x, y) Lisp_Object frame, x, y; { - CHECK_LIVE_FRAME (frame, 0); - CHECK_NUMBER (x, 2); - CHECK_NUMBER (y, 1); + CHECK_LIVE_FRAME (frame); + CHECK_NUMBER (x); + CHECK_NUMBER (y); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) - /* Warping the mouse will cause enternotify and focus events. */ + /* Warping the mouse will cause enternotify and focus events. */ x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y)); #else #if defined (MSDOS) && defined (HAVE_MOUSE) @@ -1512,15 +1543,15 @@ static void make_frame_visible_1 P_ ((Lisp_Object)); DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible, 0, 1, "", - "Make the frame FRAME visible (assuming it is an X-window).\n\ -If omitted, FRAME defaults to the currently selected frame.") - (frame) + doc: /* Make the frame FRAME visible (assuming it is an X window). +If omitted, FRAME defaults to the currently selected frame. */) + (frame) Lisp_Object frame; { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1533,7 +1564,7 @@ If omitted, FRAME defaults to the currently selected frame.") make_frame_visible_1 (XFRAME (frame)->root_window); - /* Make menu bar update for the Buffers and Frams menus. */ + /* Make menu bar update for the Buffers and Frames menus. */ windows_or_buffers_changed++; return frame; @@ -1564,17 +1595,17 @@ make_frame_visible_1 (window) DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible, 0, 2, "", - "Make the frame FRAME invisible (assuming it is an X-window).\n\ -If omitted, FRAME defaults to the currently selected frame.\n\ -Normally you may not make FRAME invisible if all other frames are invisible,\n\ -but if the second optional argument FORCE is non-nil, you may do so.") + doc: /* Make the frame FRAME invisible (assuming it is an X window). +If omitted, FRAME defaults to the currently selected frame. +Normally you may not make FRAME invisible if all other frames are invisible, +but if the second optional argument FORCE is non-nil, you may do so. */) (frame, force) Lisp_Object frame, force; { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); if (NILP (force) && !other_visible_frames (XFRAME (frame))) error ("Attempt to make invisible the sole visible or iconified frame"); @@ -1582,7 +1613,7 @@ but if the second optional argument FORCE is non-nil, you may do so.") #if 0 /* This isn't logically necessary, and it can do GC. */ /* Don't let the frame remain selected. */ if (EQ (frame, selected_frame)) - do_switch_frame (next_frame (frame, Qt), Qnil, 0) + do_switch_frame (next_frame (frame, Qt), 0, 0) #endif /* Don't allow minibuf_window to remain on a deleted frame. */ @@ -1590,7 +1621,7 @@ but if the second optional argument FORCE is non-nil, you may do so.") { struct frame *sf = XFRAME (selected_frame); Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qnil); minibuf_window = sf->minibuffer_window; } @@ -1600,7 +1631,7 @@ but if the second optional argument FORCE is non-nil, you may do so.") x_make_frame_invisible (XFRAME (frame)); #endif - /* Make menu bar update for the Buffers and Frams menus. */ + /* Make menu bar update for the Buffers and Frames menus. */ windows_or_buffers_changed++; return Qnil; @@ -1608,15 +1639,15 @@ but if the second optional argument FORCE is non-nil, you may do so.") DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame, 0, 1, "", - "Make the frame FRAME into an icon.\n\ -If omitted, FRAME defaults to the currently selected frame.") + doc: /* Make the frame FRAME into an icon. +If omitted, FRAME defaults to the currently selected frame. */) (frame) Lisp_Object frame; { if (NILP (frame)) frame = selected_frame; - - CHECK_LIVE_FRAME (frame, 0); + + CHECK_LIVE_FRAME (frame); #if 0 /* This isn't logically necessary, and it can do GC. */ /* Don't let the frame remain selected. */ @@ -1629,7 +1660,7 @@ If omitted, FRAME defaults to the currently selected frame.") { struct frame *sf = XFRAME (selected_frame); Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qnil); minibuf_window = sf->minibuffer_window; } @@ -1639,7 +1670,7 @@ If omitted, FRAME defaults to the currently selected frame.") x_iconify_frame (XFRAME (frame)); #endif - /* Make menu bar update for the Buffers and Frams menus. */ + /* Make menu bar update for the Buffers and Frames menus. */ windows_or_buffers_changed++; return Qnil; @@ -1647,14 +1678,14 @@ If omitted, FRAME defaults to the currently selected frame.") DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p, 1, 1, 0, - "Return t if FRAME is now \"visible\" (actually in use for display).\n\ -A frame that is not \"visible\" is not updated and, if it works through\n\ -a window system, it may not show at all.\n\ -Return the symbol `icon' if frame is visible only as an icon.") - (frame) + doc: /* Return t if FRAME is now \"visible\" (actually in use for display). +A frame that is not \"visible\" is not updated and, if it works through +a window system, it may not show at all. +Return the symbol `icon' if frame is visible only as an icon. */) + (frame) Lisp_Object frame; { - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); @@ -1667,7 +1698,7 @@ Return the symbol `icon' if frame is visible only as an icon.") DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list, 0, 0, 0, - "Return a list of all frames now \"visible\" (being updated).") + doc: /* Return a list of all frames now \"visible\" (being updated). */) () { Lisp_Object tail, frame; @@ -1689,18 +1720,18 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list, DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "", - "Bring FRAME to the front, so it occludes any frames it overlaps.\n\ -If FRAME is invisible, make it visible.\n\ -If you don't specify a frame, the selected frame is used.\n\ -If Emacs is displaying on an ordinary terminal or some other device which\n\ -doesn't support multiple overlapping frames, this function does nothing.") - (frame) + doc: /* Bring FRAME to the front, so it occludes any frames it overlaps. +If FRAME is invisible, make it visible. +If you don't specify a frame, the selected frame is used. +If Emacs is displaying on an ordinary terminal or some other device which +doesn't support multiple overlapping frames, this function does nothing. */) + (frame) Lisp_Object frame; { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); /* Do like the documentation says. */ Fmake_frame_visible (frame); @@ -1713,18 +1744,18 @@ doesn't support multiple overlapping frames, this function does nothing.") /* Should we have a corresponding function called Flower_Power? */ DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "", - "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\ -If you don't specify a frame, the selected frame is used.\n\ -If Emacs is displaying on an ordinary terminal or some other device which\n\ -doesn't support multiple overlapping frames, this function does nothing.") - (frame) + doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it. +If you don't specify a frame, the selected frame is used. +If Emacs is displaying on an ordinary terminal or some other device which +doesn't support multiple overlapping frames, this function does nothing. */) + (frame) Lisp_Object frame; { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); - + CHECK_LIVE_FRAME (frame); + if (frame_raise_lower_hook) (*frame_raise_lower_hook) (XFRAME (frame), 0); @@ -1734,57 +1765,57 @@ doesn't support multiple overlapping frames, this function does nothing.") DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus, 1, 2, 0, - "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\ -In other words, switch-frame events caused by events in FRAME will\n\ -request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\ -FOCUS-FRAME after reading an event typed at FRAME.\n\ -\n\ -If FOCUS-FRAME is omitted or nil, any existing redirection is\n\ -cancelled, and the frame again receives its own keystrokes.\n\ -\n\ -Focus redirection is useful for temporarily redirecting keystrokes to\n\ -a surrogate minibuffer frame when a frame doesn't have its own\n\ -minibuffer window.\n\ -\n\ -A frame's focus redirection can be changed by select-frame. If frame\n\ -FOO is selected, and then a different frame BAR is selected, any\n\ -frames redirecting their focus to FOO are shifted to redirect their\n\ -focus to BAR. This allows focus redirection to work properly when the\n\ -user switches from one frame to another using `select-window'.\n\ -\n\ -This means that a frame whose focus is redirected to itself is treated\n\ -differently from a frame whose focus is redirected to nil; the former\n\ -is affected by select-frame, while the latter is not.\n\ -\n\ -The redirection lasts until `redirect-frame-focus' is called to change it.") - (frame, focus_frame) - Lisp_Object frame, focus_frame; + doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME. +In other words, switch-frame events caused by events in FRAME will +request a switch to FOCUS-FRAME, and `last-event-frame' will be +FOCUS-FRAME after reading an event typed at FRAME. + +If FOCUS-FRAME is omitted or nil, any existing redirection is +cancelled, and the frame again receives its own keystrokes. + +Focus redirection is useful for temporarily redirecting keystrokes to +a surrogate minibuffer frame when a frame doesn't have its own +minibuffer window. + +A frame's focus redirection can be changed by select-frame. If frame +FOO is selected, and then a different frame BAR is selected, any +frames redirecting their focus to FOO are shifted to redirect their +focus to BAR. This allows focus redirection to work properly when the +user switches from one frame to another using `select-window'. + +This means that a frame whose focus is redirected to itself is treated +differently from a frame whose focus is redirected to nil; the former +is affected by select-frame, while the latter is not. + +The redirection lasts until `redirect-frame-focus' is called to change it. */) + (frame, focus_frame) + Lisp_Object frame, focus_frame; { /* Note that we don't check for a live frame here. It's reasonable to redirect the focus of a frame you're about to delete, if you know what other frame should receive those keystrokes. */ - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); if (! NILP (focus_frame)) - CHECK_LIVE_FRAME (focus_frame, 1); + CHECK_LIVE_FRAME (focus_frame); XFRAME (frame)->focus_frame = focus_frame; if (frame_rehighlight_hook) (*frame_rehighlight_hook) (XFRAME (frame)); - + return Qnil; } DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0, - "Return the frame to which FRAME's keystrokes are currently being sent.\n\ -This returns nil if FRAME's focus is not redirected.\n\ -See `redirect-frame-focus'.") - (frame) - Lisp_Object frame; + doc: /* Return the frame to which FRAME's keystrokes are currently being sent. +This returns nil if FRAME's focus is not redirected. +See `redirect-frame-focus'. */) + (frame) + Lisp_Object frame; { - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); return FRAME_FOCUS_FRAME (XFRAME (frame)); } @@ -1848,26 +1879,6 @@ frames_discard_buffer (buffer) } } -/* Move BUFFER to the end of the buffer-list of each frame. */ - -void -frames_bury_buffer (buffer) - Lisp_Object buffer; -{ - Lisp_Object frame, tail; - - FOR_EACH_FRAME (tail, frame) - { - struct frame *f = XFRAME (frame); - Lisp_Object found; - - found = Fmemq (buffer, f->buffer_list); - if (!NILP (found)) - f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list), - Fcons (buffer, Qnil)); - } -} - /* Modify the alist in *ALISTPTR to associate PROP with VAL. If the alist already has an element for PROP, we change it. */ @@ -1919,8 +1930,8 @@ set_term_frame_name (f, name) /* Check for no change needed in this very common case before we do any consing. */ - if (frame_name_fnn_p (XSTRING (f->name)->data, - STRING_BYTES (XSTRING (f->name)))) + if (frame_name_fnn_p (SDATA (f->name), + SBYTES (f->name))) return; terminal_frame_count++; @@ -1929,7 +1940,7 @@ set_term_frame_name (f, name) } else { - CHECK_STRING (name, 0); + CHECK_STRING (name); /* Don't change the name if it's already NAME. */ if (! NILP (Fstring_equal (name, f->name))) @@ -1937,7 +1948,7 @@ set_term_frame_name (f, name) /* Don't allow the user to set the frame name to F, so it doesn't clash with the names we generate for terminal frames. */ - if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name)))) + if (frame_name_fnn_p (SDATA (name), SBYTES (name))) error ("Frame names of the form F are usurped by Emacs"); } @@ -1967,7 +1978,7 @@ store_frame_param (f, prop, val) if (SYMBOLP (prop)) { Lisp_Object valcontents; - valcontents = XSYMBOL (prop)->value; + valcontents = SYMBOL_VALUE (prop); if ((BUFFER_LOCAL_VALUEP (valcontents) || SOME_BUFFER_LOCAL_VALUEP (valcontents)) && XBUFFER_LOCAL_VALUE (valcontents)->check_frame @@ -1975,6 +1986,14 @@ store_frame_param (f, prop, val) swap_in_global_binding (prop); } +#ifndef WINDOWSNT + /* The tty color mode needs to be set before the frame's parameter + alist is updated with the new value, because set_tty_color_mode + wants to look at the old mode. */ + if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)) + set_tty_color_mode (f, val); +#endif + /* Update the frame parameter alist. */ old_alist_elt = Fassq (prop, f->param_alist); if (EQ (old_alist_elt, Qnil)) @@ -1984,7 +2003,7 @@ store_frame_param (f, prop, val) /* Update some other special parameters in their special places in addition to the alist. */ - + if (EQ (prop, Qbuffer_predicate)) f->buffer_predicate = val; @@ -1999,7 +2018,7 @@ store_frame_param (f, prop, val) if (EQ (prop, Qminibuffer) && WINDOWP (val)) { if (! MINI_WINDOW_P (XWINDOW (val))) - error ("Surrogate minibuffer windows must be minibuffer windows."); + error ("Surrogate minibuffer windows must be minibuffer windows"); if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)) && !EQ (val, f->minibuffer_window)) @@ -2011,11 +2030,11 @@ store_frame_param (f, prop, val) } DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0, - "Return the parameters-alist of frame FRAME.\n\ -It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\ -The meaningful PARMs depend on the kind of frame.\n\ -If FRAME is omitted, return information on the currently selected frame.") - (frame) + doc: /* Return the parameters-alist of frame FRAME. +It is a list of elements of the form (PARM . VALUE), where PARM is a symbol. +The meaningful PARMs depend on the kind of frame. +If FRAME is omitted, return information on the currently selected frame. */) + (frame) Lisp_Object frame; { Lisp_Object alist; @@ -2023,10 +2042,10 @@ If FRAME is omitted, return information on the currently selected frame.") int height, width; struct gcpro gcpro1; - if (EQ (frame, Qnil)) + if (NILP (frame)) frame = selected_frame; - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); if (!FRAME_LIVE_P (f)) @@ -2034,25 +2053,54 @@ If FRAME is omitted, return information on the currently selected frame.") alist = Fcopy_alist (f->param_alist); GCPRO1 (alist); - + if (!FRAME_WINDOW_P (f)) { int fg = FRAME_FOREGROUND_PIXEL (f); int bg = FRAME_BACKGROUND_PIXEL (f); + Lisp_Object elt; - store_in_alist (&alist, intern ("foreground-color"), - tty_color_name (f, fg)); - store_in_alist (&alist, intern ("background-color"), - tty_color_name (f, bg)); + /* If the frame's parameter alist says the colors are + unspecified and reversed, take the frame's background pixel + for foreground and vice versa. */ + elt = Fassq (Qforeground_color, alist); + if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt))) + { + if (strncmp (SDATA (XCDR (elt)), + unspecified_bg, + SCHARS (XCDR (elt))) == 0) + store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg)); + else if (strncmp (SDATA (XCDR (elt)), + unspecified_fg, + SCHARS (XCDR (elt))) == 0) + store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg)); + } + else + store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg)); + elt = Fassq (Qbackground_color, alist); + if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt))) + { + if (strncmp (SDATA (XCDR (elt)), + unspecified_fg, + SCHARS (XCDR (elt))) == 0) + store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg)); + else if (strncmp (SDATA (XCDR (elt)), + unspecified_bg, + SCHARS (XCDR (elt))) == 0) + store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg)); + } + else + store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg)); store_in_alist (&alist, intern ("font"), build_string (FRAME_MSDOS_P (f) ? "ms-dos" - : FRAME_W32_P (f) ? "w32term" : "tty")); + : FRAME_W32_P (f) ? "w32term" + :"tty")); } store_in_alist (&alist, Qname, f->name); - height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f)); + height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); store_in_alist (&alist, Qheight, make_number (height)); - width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f)); + width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); store_in_alist (&alist, Qwidth, make_number (width)); store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil)); store_in_alist (&alist, Qminibuffer, @@ -2060,8 +2108,7 @@ If FRAME is omitted, return information on the currently selected frame.") : FRAME_MINIBUF_ONLY_P (f) ? Qonly : FRAME_MINIBUF_WINDOW (f))); store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil)); - store_in_alist (&alist, Qbuffer_list, - frame_buffer_list (selected_frame)); + store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2080,27 +2127,115 @@ If FRAME is omitted, return information on the currently selected frame.") return alist; } -DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, + +DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0, + doc: /* Return FRAME's value for parameter PARAMETER. +If FRAME is nil, describe the currently selected frame. */) + (frame, parameter) + Lisp_Object frame, parameter; +{ + struct frame *f; + Lisp_Object value; + + if (NILP (frame)) + frame = selected_frame; + else + CHECK_FRAME (frame); + CHECK_SYMBOL (parameter); + + f = XFRAME (frame); + value = Qnil; + + if (FRAME_LIVE_P (f)) + { + /* Avoid consing in frequent cases. */ + if (EQ (parameter, Qname)) + value = f->name; +#ifdef HAVE_X_WINDOWS + else if (EQ (parameter, Qdisplay) && FRAME_X_P (f)) + value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element); +#endif /* HAVE_X_WINDOWS */ + else if (EQ (parameter, Qbackground_color) + || EQ (parameter, Qforeground_color)) + { + value = Fassq (parameter, f->param_alist); + if (CONSP (value)) + { + value = XCDR (value); + /* Fframe_parameters puts the actual fg/bg color names, + even if f->param_alist says otherwise. This is + important when param_alist's notion of colors is + "unspecified". We need to do the same here. */ + if (STRINGP (value) && !FRAME_WINDOW_P (f)) + { + const char *color_name; + EMACS_INT csz; + + if (EQ (parameter, Qbackground_color)) + { + color_name = SDATA (value); + csz = SCHARS (value); + if (strncmp (color_name, unspecified_bg, csz) == 0) + value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)); + else if (strncmp (color_name, unspecified_fg, csz) == 0) + value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)); + } + else if (EQ (parameter, Qforeground_color)) + { + color_name = SDATA (value); + csz = SCHARS (value); + if (strncmp (color_name, unspecified_fg, csz) == 0) + value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)); + else if (strncmp (color_name, unspecified_bg, csz) == 0) + value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)); + } + } + } + else + value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); + } + else if (EQ (parameter, Qdisplay_type) + || EQ (parameter, Qbackground_mode)) + value = Fcdr (Fassq (parameter, f->param_alist)); + else + value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); + } + + return value; +} + + +DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, Smodify_frame_parameters, 2, 2, 0, - "Modify the parameters of frame FRAME according to ALIST.\n\ -ALIST is an alist of parameters to change and their new values.\n\ -Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\ -The meaningful PARMs depend on the kind of frame.\n\ -Undefined PARMs are ignored, but stored in the frame's parameter list\n\ -so that `frame-parameters' will return them.\n\ -\n\ -The value of frame parameter FOO can also be accessed\n\ -as a frame-local binding for the variable FOO, if you have\n\ -enabled such bindings for that variable with `make-variable-frame-local'.") - (frame, alist) + doc: /* Modify the parameters of frame FRAME according to ALIST. +If FRAME is nil, it defaults to the selected frame. +ALIST is an alist of parameters to change and their new values. +Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol. +The meaningful PARMs depend on the kind of frame. +Undefined PARMs are ignored, but stored in the frame's parameter list +so that `frame-parameters' will return them. + +The value of frame parameter FOO can also be accessed +as a frame-local binding for the variable FOO, if you have +enabled such bindings for that variable with `make-variable-frame-local'. */) + (frame, alist) Lisp_Object frame, alist; { FRAME_PTR f; register Lisp_Object tail, prop, val; + int count = SPECPDL_INDEX (); + + /* Bind this to t to inhibit initialization of the default face from + X resources in face-set-after-frame-default. If we don't inhibit + this, modifying the `font' frame parameter, for example, while + there is a `default.attributeFont' X resource, won't work, + because `default's font is reset to the value of the X resource + and that resets the `font' frame parameter. */ + specbind (Qinhibit_default_face_x_resources, Qt); if (EQ (frame, Qnil)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); f = XFRAME (frame); /* I think this should be done with a hook. */ @@ -2114,11 +2249,6 @@ enabled such bindings for that variable with `make-variable-frame-local'.") IT_set_frame_parameters (f, alist); else #endif -#ifdef macintosh - if (FRAME_MAC_P (f)) - mac_set_frame_parameters (f, alist); - else -#endif { int length = XINT (Flength (alist)); @@ -2150,14 +2280,14 @@ enabled such bindings for that variable with `make-variable-frame-local'.") } } - return Qnil; + return unbind_to (count, Qnil); } DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height, - 0, 1, 0, - "Height in pixels of a line in the font in frame FRAME.\n\ -If FRAME is omitted, the selected frame is used.\n\ -For a terminal frame, the value is always 1.") + 0, 1, 0, + doc: /* Height in pixels of a line in the font in frame FRAME. +If FRAME is omitted, the selected frame is used. +For a terminal frame, the value is always 1. */) (frame) Lisp_Object frame; { @@ -2165,7 +2295,7 @@ For a terminal frame, the value is always 1.") if (NILP (frame)) frame = selected_frame; - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); #ifdef HAVE_WINDOW_SYSTEM @@ -2178,20 +2308,20 @@ For a terminal frame, the value is always 1.") DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width, - 0, 1, 0, - "Width in pixels of characters in the font in frame FRAME.\n\ -If FRAME is omitted, the selected frame is used.\n\ -The width is the same for all characters, because\n\ -currently Emacs supports only fixed-width fonts.\n\ -For a terminal screen, the value is always 1.") - (frame) + 0, 1, 0, + doc: /* Width in pixels of characters in the font in frame FRAME. +If FRAME is omitted, the selected frame is used. +The width is the same for all characters, because +currently Emacs supports only fixed-width fonts. +For a terminal screen, the value is always 1. */) + (frame) Lisp_Object frame; { struct frame *f; if (NILP (frame)) frame = selected_frame; - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); #ifdef HAVE_WINDOW_SYSTEM @@ -2202,21 +2332,21 @@ For a terminal screen, the value is always 1.") return make_number (1); } -DEFUN ("frame-pixel-height", Fframe_pixel_height, +DEFUN ("frame-pixel-height", Fframe_pixel_height, Sframe_pixel_height, 0, 1, 0, - "Return a FRAME's height in pixels.\n\ -This counts only the height available for text lines,\n\ -not menu bars on window-system Emacs frames.\n\ -For a terminal frame, the result really gives the height in characters.\n\ -If FRAME is omitted, the selected frame is used.") - (frame) + doc: /* Return a FRAME's height in pixels. +This counts only the height available for text lines, +not menu bars on window-system Emacs frames. +For a terminal frame, the result really gives the height in characters. +If FRAME is omitted, the selected frame is used. */) + (frame) Lisp_Object frame; { struct frame *f; if (NILP (frame)) frame = selected_frame; - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); #ifdef HAVE_WINDOW_SYSTEM @@ -2224,22 +2354,22 @@ If FRAME is omitted, the selected frame is used.") return make_number (x_pixel_height (f)); else #endif - return make_number (FRAME_HEIGHT (f)); + return make_number (FRAME_LINES (f)); } -DEFUN ("frame-pixel-width", Fframe_pixel_width, +DEFUN ("frame-pixel-width", Fframe_pixel_width, Sframe_pixel_width, 0, 1, 0, - "Return FRAME's width in pixels.\n\ -For a terminal frame, the result really gives the width in characters.\n\ -If FRAME is omitted, the selected frame is used.") - (frame) + doc: /* Return FRAME's width in pixels. +For a terminal frame, the result really gives the width in characters. +If FRAME is omitted, the selected frame is used. */) + (frame) Lisp_Object frame; { struct frame *f; if (NILP (frame)) frame = selected_frame; - CHECK_FRAME (frame, 0); + CHECK_FRAME (frame); f = XFRAME (frame); #ifdef HAVE_WINDOW_SYSTEM @@ -2247,30 +2377,30 @@ If FRAME is omitted, the selected frame is used.") return make_number (x_pixel_width (f)); else #endif - return make_number (FRAME_WIDTH (f)); + return make_number (FRAME_COLS (f)); } DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0, - "Specify that the frame FRAME has LINES lines.\n\ -Optional third arg non-nil means that redisplay should use LINES lines\n\ -but that the idea of the actual height of the frame should not be changed.") - (frame, lines, pretend) + doc: /* Specify that the frame FRAME has LINES lines. +Optional third arg non-nil means that redisplay should use LINES lines +but that the idea of the actual height of the frame should not be changed. */) + (frame, lines, pretend) Lisp_Object frame, lines, pretend; { register struct frame *f; - CHECK_NUMBER (lines, 0); + CHECK_NUMBER (lines); if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) { - if (XINT (lines) != f->height) - x_set_window_size (f, 1, f->width, XINT (lines)); + if (XINT (lines) != FRAME_LINES (f)) + x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines)); do_pending_window_change (0); } else @@ -2280,25 +2410,25 @@ but that the idea of the actual height of the frame should not be changed.") } DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0, - "Specify that the frame FRAME has COLS columns.\n\ -Optional third arg non-nil means that redisplay should use COLS columns\n\ -but that the idea of the actual width of the frame should not be changed.") - (frame, cols, pretend) + doc: /* Specify that the frame FRAME has COLS columns. +Optional third arg non-nil means that redisplay should use COLS columns +but that the idea of the actual width of the frame should not be changed. */) + (frame, cols, pretend) Lisp_Object frame, cols, pretend; { register struct frame *f; - CHECK_NUMBER (cols, 0); + CHECK_NUMBER (cols); if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame, 0); + CHECK_LIVE_FRAME (frame); f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) { - if (XINT (cols) != f->width) - x_set_window_size (f, 1, XINT (cols), f->height); + if (XINT (cols) != FRAME_COLS (f)) + x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f)); do_pending_window_change (0); } else @@ -2308,23 +2438,24 @@ but that the idea of the actual width of the frame should not be changed.") } DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, - "Sets size of FRAME to COLS by ROWS, measured in characters.") - (frame, cols, rows) + doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */) + (frame, cols, rows) Lisp_Object frame, cols, rows; { register struct frame *f; - CHECK_LIVE_FRAME (frame, 0); - CHECK_NUMBER (cols, 2); - CHECK_NUMBER (rows, 1); + CHECK_LIVE_FRAME (frame); + CHECK_NUMBER (cols); + CHECK_NUMBER (rows); f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) { - if (XINT (rows) != f->height || XINT (cols) != f->width - || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f)) + if (XINT (rows) != FRAME_LINES (f) + || XINT (cols) != FRAME_COLS (f) + || f->new_text_lines || f->new_text_cols) x_set_window_size (f, 1, XINT (cols), XINT (rows)); do_pending_window_change (0); } @@ -2335,20 +2466,20 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, return Qnil; } -DEFUN ("set-frame-position", Fset_frame_position, +DEFUN ("set-frame-position", Fset_frame_position, Sset_frame_position, 3, 3, 0, - "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\ -This is actually the position of the upper left corner of the frame.\n\ -Negative values for XOFFSET or YOFFSET are interpreted relative to\n\ -the rightmost or bottommost possible position (that stays within the screen).") - (frame, xoffset, yoffset) + doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET. +This is actually the position of the upper left corner of the frame. +Negative values for XOFFSET or YOFFSET are interpreted relative to +the rightmost or bottommost possible position (that stays within the screen). */) + (frame, xoffset, yoffset) Lisp_Object frame, xoffset, yoffset; { register struct frame *f; - CHECK_LIVE_FRAME (frame, 0); - CHECK_NUMBER (xoffset, 1); - CHECK_NUMBER (yoffset, 2); + CHECK_LIVE_FRAME (frame); + CHECK_NUMBER (xoffset); + CHECK_NUMBER (yoffset); f = XFRAME (frame); /* I think this should be done with a hook. */ @@ -2361,90 +2492,1637 @@ the rightmost or bottommost possible position (that stays within the screen).") } +/*********************************************************************** + Frame Parameters + ***********************************************************************/ + +/* Connect the frame-parameter names for X frames + to the ways of passing the parameter values to the window system. + + The name of a parameter, as a Lisp symbol, + has an `x-frame-parameter' property which is an integer in Lisp + that is an index in this table. */ + +struct frame_parm_table { + char *name; + Lisp_Object *variable; +}; + +static struct frame_parm_table frame_parms[] = +{ + {"auto-raise", &Qauto_raise}, + {"auto-lower", &Qauto_lower}, + {"background-color", 0}, + {"border-color", &Qborder_color}, + {"border-width", &Qborder_width}, + {"cursor-color", &Qcursor_color}, + {"cursor-type", &Qcursor_type}, + {"font", 0}, + {"foreground-color", 0}, + {"icon-name", &Qicon_name}, + {"icon-type", &Qicon_type}, + {"internal-border-width", &Qinternal_border_width}, + {"menu-bar-lines", &Qmenu_bar_lines}, + {"mouse-color", &Qmouse_color}, + {"name", &Qname}, + {"scroll-bar-width", &Qscroll_bar_width}, + {"title", &Qtitle}, + {"unsplittable", &Qunsplittable}, + {"vertical-scroll-bars", &Qvertical_scroll_bars}, + {"visibility", &Qvisibility}, + {"tool-bar-lines", &Qtool_bar_lines}, + {"scroll-bar-foreground", &Qscroll_bar_foreground}, + {"scroll-bar-background", &Qscroll_bar_background}, + {"screen-gamma", &Qscreen_gamma}, + {"line-spacing", &Qline_spacing}, + {"left-fringe", &Qleft_fringe}, + {"right-fringe", &Qright_fringe}, + {"wait-for-wm", &Qwait_for_wm}, + {"fullscreen", &Qfullscreen}, +}; + +#ifdef HAVE_WINDOW_SYSTEM + +extern Lisp_Object Qbox; +extern Lisp_Object Qtop; + +/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the + wanted positions of the WM window (not emacs window). + Return in *WIDTH and *HEIGHT the wanted width and height of Emacs + window (FRAME_X_WINDOW). + */ + void -syms_of_frame () +x_fullscreen_adjust (f, width, height, top_pos, left_pos) + struct frame *f; + int *width; + int *height; + int *top_pos; + int *left_pos; { - syms_of_frame_1 (); + int newwidth = FRAME_COLS (f); + int newheight = FRAME_LINES (f); - staticpro (&Vframe_list); + *top_pos = f->top_pos; + *left_pos = f->left_pos; - DEFVAR_LISP ("terminal-frame", &Vterminal_frame, - "The initial frame-object, which represents Emacs's stdout."); + if (f->want_fullscreen & FULLSCREEN_HEIGHT) + { + int ph; - DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, - "Non-nil if all of emacs is iconified and frame updates are not needed."); - Vemacs_iconified = Qnil; + ph = FRAME_X_DISPLAY_INFO (f)->height; + newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); + ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff; + newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); + *top_pos = 0; + } - DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function, - "If non-nil, function applied to the normal result of `mouse-position'.\n\ -This abnormal hook exists for the benefit of packages like XTerm-mouse\n\ -which need to do mouse handling at the Lisp level."); - Vmouse_position_function = Qnil; + if (f->want_fullscreen & FULLSCREEN_WIDTH) + { + int pw; - DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, - "Minibufferless frames use this frame's minibuffer.\n\ -\n\ -Emacs cannot create minibufferless frames unless this is set to an\n\ -appropriate surrogate.\n\ -\n\ -Emacs consults this variable only when creating minibufferless\n\ -frames; once the frame is created, it sticks with its assigned\n\ -minibuffer, no matter what this variable is set to. This means that\n\ -this variable doesn't necessarily say anything meaningful about the\n\ -current set of frames, or where the minibuffer is currently being\n\ -displayed."); + pw = FRAME_X_DISPLAY_INFO (f)->width; + newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); + pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff; + newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); + *left_pos = 0; + } - defsubr (&Sactive_minibuffer_window); - defsubr (&Sframep); - defsubr (&Sframe_live_p); - defsubr (&Smake_terminal_frame); - defsubr (&Shandle_switch_frame); - defsubr (&Signore_event); - defsubr (&Sselect_frame); - defsubr (&Sselected_frame); - defsubr (&Swindow_frame); - defsubr (&Sframe_root_window); - defsubr (&Sframe_first_window); - defsubr (&Sframe_selected_window); - defsubr (&Sset_frame_selected_window); - defsubr (&Sframe_list); - defsubr (&Snext_frame); - defsubr (&Sprevious_frame); - defsubr (&Sdelete_frame); - defsubr (&Smouse_position); - defsubr (&Smouse_pixel_position); - defsubr (&Sset_mouse_position); - defsubr (&Sset_mouse_pixel_position); -#if 0 - defsubr (&Sframe_configuration); - defsubr (&Srestore_frame_configuration); -#endif - defsubr (&Smake_frame_visible); - defsubr (&Smake_frame_invisible); - defsubr (&Siconify_frame); - defsubr (&Sframe_visible_p); - defsubr (&Svisible_frame_list); - defsubr (&Sraise_frame); - defsubr (&Slower_frame); - defsubr (&Sredirect_frame_focus); - defsubr (&Sframe_focus); - defsubr (&Sframe_parameters); - defsubr (&Smodify_frame_parameters); - defsubr (&Sframe_char_height); - defsubr (&Sframe_char_width); - defsubr (&Sframe_pixel_height); - defsubr (&Sframe_pixel_width); - defsubr (&Sset_frame_height); - defsubr (&Sset_frame_width); - defsubr (&Sset_frame_size); - defsubr (&Sset_frame_position); + *width = newwidth; + *height = newheight; } + +/* Change the parameters of frame F as specified by ALIST. + If a parameter is not specially recognized, do nothing special; + otherwise call the `x_set_...' function for that parameter. + Except for certain geometry properties, always call store_frame_param + to store the new value in the parameter alist. */ + void -keys_of_frame () +x_set_frame_parameters (f, alist) + FRAME_PTR f; + Lisp_Object alist; { - initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame"); - initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame"); - initial_define_lispy_key (global_map, "iconify-frame", "ignore-event"); - initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event"); -} + Lisp_Object tail; + + /* If both of these parameters are present, it's more efficient to + set them both at once. So we wait until we've looked at the + entire list before we set them. */ + int width, height; + + /* Same here. */ + Lisp_Object left, top; + + /* Same with these. */ + Lisp_Object icon_left, icon_top; + + /* Record in these vectors all the parms specified. */ + Lisp_Object *parms; + Lisp_Object *values; + int i, p; + int left_no_change = 0, top_no_change = 0; + int icon_left_no_change = 0, icon_top_no_change = 0; + int fullscreen_is_being_set = 0; + + struct gcpro gcpro1, gcpro2; + + i = 0; + for (tail = alist; CONSP (tail); tail = Fcdr (tail)) + i++; + + parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); + values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); + + /* Extract parm names and values into those vectors. */ + + i = 0; + for (tail = alist; CONSP (tail); tail = Fcdr (tail)) + { + Lisp_Object elt; + + elt = Fcar (tail); + parms[i] = Fcar (elt); + values[i] = Fcdr (elt); + i++; + } + /* TAIL and ALIST are not used again below here. */ + alist = tail = Qnil; + + GCPRO2 (*parms, *values); + gcpro1.nvars = i; + gcpro2.nvars = i; + + /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, + because their values appear in VALUES and strings are not valid. */ + top = left = Qunbound; + icon_left = icon_top = Qunbound; + + /* Provide default values for HEIGHT and WIDTH. */ + width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); + height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); + + /* Process foreground_color and background_color before anything else. + They are independent of other properties, but other properties (e.g., + cursor_color) are dependent upon them. */ + /* Process default font as well, since fringe widths depends on it. */ + /* Also, process fullscreen, width and height depend upon that */ + for (p = 0; p < i; p++) + { + Lisp_Object prop, val; + + prop = parms[p]; + val = values[p]; + if (EQ (prop, Qforeground_color) + || EQ (prop, Qbackground_color) + || EQ (prop, Qfont) + || EQ (prop, Qfullscreen)) + { + register Lisp_Object param_index, old_value; + + old_value = get_frame_param (f, prop); + fullscreen_is_being_set |= EQ (prop, Qfullscreen); + + if (NILP (Fequal (val, old_value))) + { + store_frame_param (f, prop, val); + + param_index = Fget (prop, Qx_frame_parameter); + if (NATNUMP (param_index) + && (XFASTINT (param_index) + < sizeof (frame_parms)/sizeof (frame_parms[0])) + && rif->frame_parm_handlers[XINT (param_index)]) + (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); + } + } + } + + /* Now process them in reverse of specified order. */ + for (i--; i >= 0; i--) + { + Lisp_Object prop, val; + + prop = parms[i]; + val = values[i]; + + if (EQ (prop, Qwidth) && NUMBERP (val)) + width = XFASTINT (val); + else if (EQ (prop, Qheight) && NUMBERP (val)) + height = XFASTINT (val); + else if (EQ (prop, Qtop)) + top = val; + else if (EQ (prop, Qleft)) + left = val; + else if (EQ (prop, Qicon_top)) + icon_top = val; + else if (EQ (prop, Qicon_left)) + icon_left = val; + else if (EQ (prop, Qforeground_color) + || EQ (prop, Qbackground_color) + || EQ (prop, Qfont) + || EQ (prop, Qfullscreen)) + /* Processed above. */ + continue; + else + { + register Lisp_Object param_index, old_value; + + old_value = get_frame_param (f, prop); + + store_frame_param (f, prop, val); + + param_index = Fget (prop, Qx_frame_parameter); + if (NATNUMP (param_index) + && (XFASTINT (param_index) + < sizeof (frame_parms)/sizeof (frame_parms[0])) + && rif->frame_parm_handlers[XINT (param_index)]) + (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); + } + } + + /* Don't die if just one of these was set. */ + if (EQ (left, Qunbound)) + { + left_no_change = 1; + if (f->left_pos < 0) + left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil)); + else + XSETINT (left, f->left_pos); + } + if (EQ (top, Qunbound)) + { + top_no_change = 1; + if (f->top_pos < 0) + top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil)); + else + XSETINT (top, f->top_pos); + } + + /* If one of the icon positions was not set, preserve or default it. */ + if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left)) + { + icon_left_no_change = 1; + icon_left = Fcdr (Fassq (Qicon_left, f->param_alist)); + if (NILP (icon_left)) + XSETINT (icon_left, 0); + } + if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top)) + { + icon_top_no_change = 1; + icon_top = Fcdr (Fassq (Qicon_top, f->param_alist)); + if (NILP (icon_top)) + XSETINT (icon_top, 0); + } + +#ifndef HAVE_CARBON + /* MAC_TODO: fullscreen */ + if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) + { + /* If the frame is visible already and the fullscreen parameter is + being set, it is too late to set WM manager hints to specify + size and position. + Here we first get the width, height and position that applies to + fullscreen. We then move the frame to the appropriate + position. Resize of the frame is taken care of in the code after + this if-statement. */ + int new_left, new_top; + + x_fullscreen_adjust (f, &width, &height, &new_top, &new_left); + if (new_top != f->top_pos || new_left != f->left_pos) + x_set_offset (f, new_left, new_top, 1); + } +#endif + + /* Don't set these parameters unless they've been explicitly + specified. The window might be mapped or resized while we're in + this function, and we don't want to override that unless the lisp + code has asked for it. + + Don't set these parameters unless they actually differ from the + window's current parameters; the window may not actually exist + yet. */ + { + Lisp_Object frame; + + check_frame_size (f, &height, &width); + + XSETFRAME (frame, f); + + if (width != FRAME_COLS (f) + || height != FRAME_LINES (f) + || f->new_text_lines || f->new_text_cols) + Fset_frame_size (frame, make_number (width), make_number (height)); + + if ((!NILP (left) || !NILP (top)) + && ! (left_no_change && top_no_change) + && ! (NUMBERP (left) && XINT (left) == f->left_pos + && NUMBERP (top) && XINT (top) == f->top_pos)) + { + int leftpos = 0; + int toppos = 0; + + /* Record the signs. */ + f->size_hint_flags &= ~ (XNegative | YNegative); + if (EQ (left, Qminus)) + f->size_hint_flags |= XNegative; + else if (INTEGERP (left)) + { + leftpos = XINT (left); + if (leftpos < 0) + f->size_hint_flags |= XNegative; + } + else if (CONSP (left) && EQ (XCAR (left), Qminus) + && CONSP (XCDR (left)) + && INTEGERP (XCAR (XCDR (left)))) + { + leftpos = - XINT (XCAR (XCDR (left))); + f->size_hint_flags |= XNegative; + } + else if (CONSP (left) && EQ (XCAR (left), Qplus) + && CONSP (XCDR (left)) + && INTEGERP (XCAR (XCDR (left)))) + { + leftpos = XINT (XCAR (XCDR (left))); + } + + if (EQ (top, Qminus)) + f->size_hint_flags |= YNegative; + else if (INTEGERP (top)) + { + toppos = XINT (top); + if (toppos < 0) + f->size_hint_flags |= YNegative; + } + else if (CONSP (top) && EQ (XCAR (top), Qminus) + && CONSP (XCDR (top)) + && INTEGERP (XCAR (XCDR (top)))) + { + toppos = - XINT (XCAR (XCDR (top))); + f->size_hint_flags |= YNegative; + } + else if (CONSP (top) && EQ (XCAR (top), Qplus) + && CONSP (XCDR (top)) + && INTEGERP (XCAR (XCDR (top)))) + { + toppos = XINT (XCAR (XCDR (top))); + } + + + /* Store the numeric value of the position. */ + f->top_pos = toppos; + f->left_pos = leftpos; + + f->win_gravity = NorthWestGravity; + + /* Actually set that position, and convert to absolute. */ + x_set_offset (f, leftpos, toppos, -1); + } + + if ((!NILP (icon_left) || !NILP (icon_top)) + && ! (icon_left_no_change && icon_top_no_change)) + x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); + } + + UNGCPRO; +} + + +/* Insert a description of internally-recorded parameters of frame X + into the parameter alist *ALISTPTR that is to be given to the user. + Only parameters that are specific to the X window system + and whose values are not correctly recorded in the frame's + param_alist need to be considered here. */ + +void +x_report_frame_params (f, alistptr) + struct frame *f; + Lisp_Object *alistptr; +{ + char buf[16]; + Lisp_Object tem; + + /* Represent negative positions (off the top or left screen edge) + in a way that Fmodify_frame_parameters will understand correctly. */ + XSETINT (tem, f->left_pos); + if (f->left_pos >= 0) + store_in_alist (alistptr, Qleft, tem); + else + store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); + + XSETINT (tem, f->top_pos); + if (f->top_pos >= 0) + store_in_alist (alistptr, Qtop, tem); + else + store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); + + store_in_alist (alistptr, Qborder_width, + make_number (f->border_width)); + store_in_alist (alistptr, Qinternal_border_width, + make_number (FRAME_INTERNAL_BORDER_WIDTH (f))); + store_in_alist (alistptr, Qleft_fringe, + make_number (FRAME_LEFT_FRINGE_WIDTH (f))); + store_in_alist (alistptr, Qright_fringe, + make_number (FRAME_RIGHT_FRINGE_WIDTH (f))); + store_in_alist (alistptr, Qscroll_bar_width, + (! FRAME_HAS_VERTICAL_SCROLL_BARS (f) + ? make_number (0) + : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 + ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) + /* nil means "use default width" + for non-toolkit scroll bar. + ruler-mode.el depends on this. */ + : Qnil)); + sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); + store_in_alist (alistptr, Qwindow_id, + build_string (buf)); +#ifdef HAVE_X_WINDOWS +#ifdef USE_X_TOOLKIT + /* Tooltip frame may not have this widget. */ + if (FRAME_X_OUTPUT (f)->widget) +#endif + sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f)); + store_in_alist (alistptr, Qouter_window_id, + build_string (buf)); +#endif + store_in_alist (alistptr, Qicon_name, f->icon_name); + FRAME_SAMPLE_VISIBILITY (f); + store_in_alist (alistptr, Qvisibility, + (FRAME_VISIBLE_P (f) ? Qt + : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); + store_in_alist (alistptr, Qdisplay, + XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); + +#ifndef HAVE_CARBON +/* A Mac Window is identified by a struct, not an integer. */ + if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) + tem = Qnil; + else + XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); + store_in_alist (alistptr, Qparent_id, tem); +#endif +} + + +/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is + the previous value of that parameter, NEW_VALUE is the new value. */ + +void +x_set_fullscreen (f, new_value, old_value) + struct frame *f; + Lisp_Object new_value, old_value; +{ +#ifndef HAVE_CARBON + if (NILP (new_value)) + f->want_fullscreen = FULLSCREEN_NONE; + else if (EQ (new_value, Qfullboth)) + f->want_fullscreen = FULLSCREEN_BOTH; + else if (EQ (new_value, Qfullwidth)) + f->want_fullscreen = FULLSCREEN_WIDTH; + else if (EQ (new_value, Qfullheight)) + f->want_fullscreen = FULLSCREEN_HEIGHT; +#endif +} + + +/* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is + the previous value of that parameter, NEW_VALUE is the new value. */ + +void +x_set_line_spacing (f, new_value, old_value) + struct frame *f; + Lisp_Object new_value, old_value; +{ + if (NILP (new_value)) + f->extra_line_spacing = 0; + else if (NATNUMP (new_value)) + f->extra_line_spacing = XFASTINT (new_value); + else + Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"), + Fcons (new_value, Qnil))); + if (FRAME_VISIBLE_P (f)) + redraw_frame (f); +} + + +/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is + the previous value of that parameter, NEW_VALUE is the new value. */ + +void +x_set_screen_gamma (f, new_value, old_value) + struct frame *f; + Lisp_Object new_value, old_value; +{ + if (NILP (new_value)) + f->gamma = 0; + else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0) + /* The value 0.4545 is the normal viewing gamma. */ + f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value)); + else + Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"), + Fcons (new_value, Qnil))); + + clear_face_cache (0); +} + + +void +x_set_font (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + Lisp_Object result; + Lisp_Object fontset_name; + Lisp_Object frame; + int old_fontset = FRAME_FONTSET(f); + + CHECK_STRING (arg); + + fontset_name = Fquery_fontset (arg, Qnil); + + BLOCK_INPUT; + result = (STRINGP (fontset_name) + ? x_new_fontset (f, SDATA (fontset_name)) + : x_new_font (f, SDATA (arg))); + UNBLOCK_INPUT; + + if (EQ (result, Qnil)) + error ("Font `%s' is not defined", SDATA (arg)); + else if (EQ (result, Qt)) + error ("The characters of the given font have varying widths"); + else if (STRINGP (result)) + { + if (STRINGP (fontset_name)) + { + /* Fontset names are built from ASCII font names, so the + names may be equal despite there was a change. */ + if (old_fontset == FRAME_FONTSET (f)) + return; + } + else if (!NILP (Fequal (result, oldval))) + return; + + store_frame_param (f, Qfont, result); + recompute_basic_faces (f); + } + else + abort (); + + do_pending_window_change (0); + + /* Don't call `face-set-after-frame-default' when faces haven't been + initialized yet. This is the case when called from + Fx_create_frame. In that case, the X widget or window doesn't + exist either, and we can end up in x_report_frame_params with a + null widget which gives a segfault. */ + if (FRAME_FACE_CACHE (f)) + { + XSETFRAME (frame, f); + call1 (Qface_set_after_frame_default, frame); + } +} + + +void +x_set_fringe_width (f, new_value, old_value) + struct frame *f; + Lisp_Object new_value, old_value; +{ + compute_fringe_widths (f, 1); +} + +void +x_set_border_width (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + CHECK_NUMBER (arg); + + if (XINT (arg) == f->border_width) + return; + +#ifndef HAVE_CARBON + if (FRAME_X_WINDOW (f) != 0) + error ("Cannot change the border width of a window"); +#endif /* MAC_TODO */ + + f->border_width = XINT (arg); +} + +void +x_set_internal_border_width (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + int old = FRAME_INTERNAL_BORDER_WIDTH (f); + + CHECK_NUMBER (arg); + FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg); + if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0) + FRAME_INTERNAL_BORDER_WIDTH (f) = 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_INTERNAL_BORDER_WIDTH (f) == old) + return; + + if (FRAME_X_WINDOW (f) != 0) + { + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + SET_FRAME_GARBAGED (f); + do_pending_window_change (0); + } + else + SET_FRAME_GARBAGED (f); +} + +void +x_set_visibility (f, value, oldval) + struct frame *f; + Lisp_Object value, oldval; +{ + Lisp_Object frame; + XSETFRAME (frame, f); + + if (NILP (value)) + Fmake_frame_invisible (frame, Qt); + else if (EQ (value, Qicon)) + Ficonify_frame (frame); + else + Fmake_frame_visible (frame); +} + +void +x_set_autoraise (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + f->auto_raise = !EQ (Qnil, arg); +} + +void +x_set_autolower (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + f->auto_lower = !EQ (Qnil, arg); +} + +void +x_set_unsplittable (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + f->no_split = !NILP (arg); +} + +void +x_set_vertical_scroll_bars (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) + || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) + || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))) + { + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) + = (NILP (arg) + ? vertical_scroll_bar_none + : EQ (Qleft, arg) + ? vertical_scroll_bar_left + : EQ (Qright, arg) + ? vertical_scroll_bar_right + : EQ (Qleft, Vdefault_frame_scroll_bars) + ? vertical_scroll_bar_left + : EQ (Qright, Vdefault_frame_scroll_bars) + ? vertical_scroll_bar_right + : vertical_scroll_bar_none); + + /* We set this parameter before creating the X window for the + frame, so we can get the geometry right from the start. + However, if the window hasn't been created yet, we shouldn't + call x_set_window_size. */ + if (FRAME_X_WINDOW (f)) + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + do_pending_window_change (0); + } +} + +void +x_set_scroll_bar_width (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + int wid = FRAME_COLUMN_WIDTH (f); + + if (NILP (arg)) + { + x_set_scroll_bar_default_width (f); + + if (FRAME_X_WINDOW (f)) + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + do_pending_window_change (0); + } + else if (INTEGERP (arg) && XINT (arg) > 0 + && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) + { + if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) + XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1); + + FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); + FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; + if (FRAME_X_WINDOW (f)) + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + do_pending_window_change (0); + } + + change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0); + XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; + XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; +} + + + +/* Return non-nil if frame F wants a bitmap icon. */ + +Lisp_Object +x_icon_type (f) + FRAME_PTR f; +{ + Lisp_Object tem; + + tem = assq_no_quit (Qicon_type, f->param_alist); + if (CONSP (tem)) + return XCDR (tem); + else + return Qnil; +} + + +/* Subroutines of creating an X frame. */ + +/* Make sure that Vx_resource_name is set to a reasonable value. + Fix it up, or set it to `emacs' if it is too hopeless. */ + +void +validate_x_resource_name () +{ + int len = 0; + /* Number of valid characters in the resource name. */ + int good_count = 0; + /* Number of invalid characters in the resource name. */ + int bad_count = 0; + Lisp_Object new; + int i; + + if (!STRINGP (Vx_resource_class)) + Vx_resource_class = build_string (EMACS_CLASS); + + if (STRINGP (Vx_resource_name)) + { + unsigned char *p = SDATA (Vx_resource_name); + int i; + + len = SBYTES (Vx_resource_name); + + /* Only letters, digits, - and _ are valid in resource names. + Count the valid characters and count the invalid ones. */ + for (i = 0; i < len; i++) + { + int c = p[i]; + if (! ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == '-' || c == '_')) + bad_count++; + else + good_count++; + } + } + else + /* Not a string => completely invalid. */ + bad_count = 5, good_count = 0; + + /* If name is valid already, return. */ + if (bad_count == 0) + return; + + /* If name is entirely invalid, or nearly so, use `emacs'. */ + if (good_count == 0 + || (good_count == 1 && bad_count > 0)) + { + Vx_resource_name = build_string ("emacs"); + return; + } + + /* Name is partly valid. Copy it and replace the invalid characters + with underscores. */ + + Vx_resource_name = new = Fcopy_sequence (Vx_resource_name); + + for (i = 0; i < len; i++) + { + int c = SREF (new, i); + if (! ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == '-' || c == '_')) + SSET (new, i, '_'); + } +} + + +extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *)); +extern Display_Info *check_x_display_info P_ ((Lisp_Object)); + + +/* Get specified attribute from resource database RDB. + See Fx_get_resource below for other parameters. */ + +static Lisp_Object +xrdb_get_resource (rdb, attribute, class, component, subclass) + XrmDatabase rdb; + Lisp_Object attribute, class, component, subclass; +{ + register char *value; + char *name_key; + char *class_key; + + CHECK_STRING (attribute); + CHECK_STRING (class); + + if (!NILP (component)) + CHECK_STRING (component); + if (!NILP (subclass)) + CHECK_STRING (subclass); + if (NILP (component) != NILP (subclass)) + error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither"); + + validate_x_resource_name (); + + /* Allocate space for the components, the dots which separate them, + and the final '\0'. Make them big enough for the worst case. */ + name_key = (char *) alloca (SBYTES (Vx_resource_name) + + (STRINGP (component) + ? SBYTES (component) : 0) + + SBYTES (attribute) + + 3); + + class_key = (char *) alloca (SBYTES (Vx_resource_class) + + SBYTES (class) + + (STRINGP (subclass) + ? SBYTES (subclass) : 0) + + 3); + + /* Start with emacs.FRAMENAME for the name (the specific one) + and with `Emacs' for the class key (the general one). */ + strcpy (name_key, SDATA (Vx_resource_name)); + strcpy (class_key, SDATA (Vx_resource_class)); + + strcat (class_key, "."); + strcat (class_key, SDATA (class)); + + if (!NILP (component)) + { + strcat (class_key, "."); + strcat (class_key, SDATA (subclass)); + + strcat (name_key, "."); + strcat (name_key, SDATA (component)); + } + + strcat (name_key, "."); + strcat (name_key, SDATA (attribute)); + + value = x_get_string_resource (rdb, name_key, class_key); + + if (value != (char *) 0) + return build_string (value); + else + return Qnil; +} + + +DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0, + doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database. +This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the +class, where INSTANCE is the name under which Emacs was invoked, or +the name specified by the `-name' or `-rn' command-line arguments. + +The optional arguments COMPONENT and SUBCLASS add to the key and the +class, respectively. You must specify both of them or neither. +If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE' +and the class is `Emacs.CLASS.SUBCLASS'. */) + (attribute, class, component, subclass) + Lisp_Object attribute, class, component, subclass; +{ +#ifdef HAVE_X_WINDOWS + check_x (); +#endif + + return xrdb_get_resource (check_x_display_info (Qnil)->xrdb, + attribute, class, component, subclass); +} + +/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */ + +Lisp_Object +display_x_get_resource (dpyinfo, attribute, class, component, subclass) + Display_Info *dpyinfo; + Lisp_Object attribute, class, component, subclass; +{ + return xrdb_get_resource (dpyinfo->xrdb, + attribute, class, component, subclass); +} + +/* Used when C code wants a resource value. */ + +char * +x_get_resource_string (attribute, class) + char *attribute, *class; +{ + char *name_key; + char *class_key; + struct frame *sf = SELECTED_FRAME (); + + /* Allocate space for the components, the dots which separate them, + and the final '\0'. */ + name_key = (char *) alloca (SBYTES (Vinvocation_name) + + strlen (attribute) + 2); + class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) + + strlen (class) + 2); + + sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute); + sprintf (class_key, "%s.%s", EMACS_CLASS, class); + + return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, + name_key, class_key); +} + + +/* Return the value of parameter PARAM. + + First search ALIST, then Vdefault_frame_alist, then the X defaults + database, using ATTRIBUTE as the attribute name and CLASS as its class. + + Convert the resource to the type specified by desired_type. + + If no default is specified, return Qunbound. If you call + x_get_arg, make sure you deal with Qunbound in a reasonable way, + and don't let it get stored in any Lisp-visible variables! */ + +Lisp_Object +x_get_arg (dpyinfo, alist, param, attribute, class, type) + Display_Info *dpyinfo; + Lisp_Object alist, param; + char *attribute; + char *class; + enum resource_types type; +{ + register Lisp_Object tem; + + tem = Fassq (param, alist); + if (EQ (tem, Qnil)) + tem = Fassq (param, Vdefault_frame_alist); + if (EQ (tem, Qnil)) + { + if (attribute) + { + tem = display_x_get_resource (dpyinfo, + build_string (attribute), + build_string (class), + Qnil, Qnil); + + if (NILP (tem)) + return Qunbound; + + switch (type) + { + case RES_TYPE_NUMBER: + return make_number (atoi (SDATA (tem))); + + case RES_TYPE_FLOAT: + return make_float (atof (SDATA (tem))); + + case RES_TYPE_BOOLEAN: + tem = Fdowncase (tem); + if (!strcmp (SDATA (tem), "on") + || !strcmp (SDATA (tem), "true")) + return Qt; + else + return Qnil; + + case RES_TYPE_STRING: + return tem; + + case RES_TYPE_SYMBOL: + /* As a special case, we map the values `true' and `on' + to Qt, and `false' and `off' to Qnil. */ + { + Lisp_Object lower; + lower = Fdowncase (tem); + if (!strcmp (SDATA (lower), "on") + || !strcmp (SDATA (lower), "true")) + return Qt; + else if (!strcmp (SDATA (lower), "off") + || !strcmp (SDATA (lower), "false")) + return Qnil; + else + return Fintern (tem, Qnil); + } + + default: + abort (); + } + } + else + return Qunbound; + } + return Fcdr (tem); +} + +Lisp_Object +x_frame_get_arg (f, alist, param, attribute, class, type) + struct frame *f; + Lisp_Object alist, param; + char *attribute; + char *class; + enum resource_types type; +{ + return x_get_arg (FRAME_X_DISPLAY_INFO (f), + alist, param, attribute, class, type); +} + +/* Like x_frame_get_arg, but also record the value in f->param_alist. */ + +Lisp_Object +x_frame_get_and_record_arg (f, alist, param, attribute, class, type) + struct frame *f; + Lisp_Object alist, param; + char *attribute; + char *class; + enum resource_types type; +{ + Lisp_Object value; + + value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param, + attribute, class, type); + if (! NILP (value)) + store_frame_param (f, param, value); + + return value; +} + + +/* Record in frame F the specified or default value according to ALIST + of the parameter named PROP (a Lisp symbol). + If no value is specified for PROP, look for an X default for XPROP + on the frame named NAME. + If that is not found either, use the value DEFLT. */ + +Lisp_Object +x_default_parameter (f, alist, prop, deflt, xprop, xclass, type) + struct frame *f; + Lisp_Object alist; + Lisp_Object prop; + Lisp_Object deflt; + char *xprop; + char *xclass; + enum resource_types type; +{ + Lisp_Object tem; + + tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type); + if (EQ (tem, Qunbound)) + tem = deflt; + x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); + return tem; +} + + + + +DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0, + doc: /* Parse an X-style geometry string STRING. +Returns an alist of the form ((top . TOP), (left . LEFT) ... ). +The properties returned may include `top', `left', `height', and `width'. +The value of `left' or `top' may be an integer, +or a list (+ N) meaning N pixels relative to top/left corner, +or a list (- N) meaning -N pixels relative to bottom/right corner. */) + (string) + Lisp_Object string; +{ + int geometry, x, y; + unsigned int width, height; + Lisp_Object result; + + CHECK_STRING (string); + + geometry = XParseGeometry ((char *) SDATA (string), + &x, &y, &width, &height); + +#if 0 + if (!!(geometry & XValue) != !!(geometry & YValue)) + error ("Must specify both x and y position, or neither"); +#endif + + result = Qnil; + if (geometry & XValue) + { + Lisp_Object element; + + if (x >= 0 && (geometry & XNegative)) + element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil))); + else if (x < 0 && ! (geometry & XNegative)) + element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil))); + else + element = Fcons (Qleft, make_number (x)); + result = Fcons (element, result); + } + + if (geometry & YValue) + { + Lisp_Object element; + + if (y >= 0 && (geometry & YNegative)) + element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil))); + else if (y < 0 && ! (geometry & YNegative)) + element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil))); + else + element = Fcons (Qtop, make_number (y)); + result = Fcons (element, result); + } + + if (geometry & WidthValue) + result = Fcons (Fcons (Qwidth, make_number (width)), result); + if (geometry & HeightValue) + result = Fcons (Fcons (Qheight, make_number (height)), result); + + return result; +} + +/* Calculate the desired size and position of frame F. + Return the flags saying which aspects were specified. + + Also set the win_gravity and size_hint_flags of F. + + Adjust height for toolbar if TOOLBAR_P is 1. + + This function does not make the coordinates positive. */ + +#define DEFAULT_ROWS 40 +#define DEFAULT_COLS 80 + +int +x_figure_window_size (f, parms, toolbar_p) + struct frame *f; + Lisp_Object parms; + int toolbar_p; +{ + register Lisp_Object tem0, tem1, tem2; + long window_prompting = 0; + Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + + /* Default values if we fall through. + Actually, if that happens we should get + window manager prompting. */ + SET_FRAME_COLS (f, DEFAULT_COLS); + FRAME_LINES (f) = DEFAULT_ROWS; + /* Window managers expect that if program-specified + positions are not (0,0), they're intentional, not defaults. */ + f->top_pos = 0; + f->left_pos = 0; + + /* Ensure that old new_text_cols and new_text_lines will not override the + values set here. */ + /* ++KFS: This was specific to W32, but seems ok for all platforms */ + f->new_text_cols = f->new_text_lines = 0; + + tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER); + tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER); + tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER); + if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) + { + if (!EQ (tem0, Qunbound)) + { + CHECK_NUMBER (tem0); + FRAME_LINES (f) = XINT (tem0); + } + if (!EQ (tem1, Qunbound)) + { + CHECK_NUMBER (tem1); + SET_FRAME_COLS (f, XINT (tem1)); + } + if (!NILP (tem2) && !EQ (tem2, Qunbound)) + window_prompting |= USSize; + else + window_prompting |= PSize; + } + + f->scroll_bar_actual_width + = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); + + /* This used to be done _before_ calling x_figure_window_size, but + since the height is reset here, this was really a no-op. I + assume that moving it here does what Gerd intended (although he + no longer can remember what that was... ++KFS, 2003-03-25. */ + + /* Add the tool-bar height to the initial frame height so that the + user gets a text display area of the size he specified with -g or + via .Xdefaults. Later changes of the tool-bar height don't + change the frame size. This is done so that users can create + tall Emacs frames without having to guess how tall the tool-bar + will get. */ + if (toolbar_p && FRAME_TOOL_BAR_LINES (f)) + { + int margin, relief, bar_height; + + relief = (tool_bar_button_relief >= 0 + ? tool_bar_button_relief + : DEFAULT_TOOL_BAR_BUTTON_RELIEF); + + if (INTEGERP (Vtool_bar_button_margin) + && XINT (Vtool_bar_button_margin) > 0) + margin = XFASTINT (Vtool_bar_button_margin); + else if (CONSP (Vtool_bar_button_margin) + && INTEGERP (XCDR (Vtool_bar_button_margin)) + && XINT (XCDR (Vtool_bar_button_margin)) > 0) + margin = XFASTINT (XCDR (Vtool_bar_button_margin)); + else + margin = 0; + + bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; + FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); + } + + compute_fringe_widths (f, 0); + + FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f)); + FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); + + tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER); + tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER); + tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER); + if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) + { + if (EQ (tem0, Qminus)) + { + f->top_pos = 0; + window_prompting |= YNegative; + } + else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) + && CONSP (XCDR (tem0)) + && INTEGERP (XCAR (XCDR (tem0)))) + { + f->top_pos = - XINT (XCAR (XCDR (tem0))); + window_prompting |= YNegative; + } + else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) + && CONSP (XCDR (tem0)) + && INTEGERP (XCAR (XCDR (tem0)))) + { + f->top_pos = XINT (XCAR (XCDR (tem0))); + } + else if (EQ (tem0, Qunbound)) + f->top_pos = 0; + else + { + CHECK_NUMBER (tem0); + f->top_pos = XINT (tem0); + if (f->top_pos < 0) + window_prompting |= YNegative; + } + + if (EQ (tem1, Qminus)) + { + f->left_pos = 0; + window_prompting |= XNegative; + } + else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) + && CONSP (XCDR (tem1)) + && INTEGERP (XCAR (XCDR (tem1)))) + { + f->left_pos = - XINT (XCAR (XCDR (tem1))); + window_prompting |= XNegative; + } + else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) + && CONSP (XCDR (tem1)) + && INTEGERP (XCAR (XCDR (tem1)))) + { + f->left_pos = XINT (XCAR (XCDR (tem1))); + } + else if (EQ (tem1, Qunbound)) + f->left_pos = 0; + else + { + CHECK_NUMBER (tem1); + f->left_pos = XINT (tem1); + if (f->left_pos < 0) + window_prompting |= XNegative; + } + + if (!NILP (tem2) && ! EQ (tem2, Qunbound)) + window_prompting |= USPosition; + else + window_prompting |= PPosition; + } + + if (f->want_fullscreen != FULLSCREEN_NONE) + { + int left, top; + int width, height; + + /* It takes both for some WM:s to place it where we want */ + window_prompting = USPosition | PPosition; + x_fullscreen_adjust (f, &width, &height, &top, &left); + FRAME_COLS (f) = width; + FRAME_LINES (f) = height; + FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); + FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); + f->left_pos = left; + f->top_pos = top; + } + + if (window_prompting & XNegative) + { + if (window_prompting & YNegative) + f->win_gravity = SouthEastGravity; + else + f->win_gravity = NorthEastGravity; + } + else + { + if (window_prompting & YNegative) + f->win_gravity = SouthWestGravity; + else + f->win_gravity = NorthWestGravity; + } + + f->size_hint_flags = window_prompting; + + return window_prompting; +} + + + +#endif /* HAVE_WINDOW_SYSTEM */ + + + +/*********************************************************************** + Initialization + ***********************************************************************/ + +void +syms_of_frame () +{ + Qframep = intern ("framep"); + staticpro (&Qframep); + Qframe_live_p = intern ("frame-live-p"); + staticpro (&Qframe_live_p); + Qheight = intern ("height"); + staticpro (&Qheight); + Qicon = intern ("icon"); + staticpro (&Qicon); + Qminibuffer = intern ("minibuffer"); + staticpro (&Qminibuffer); + Qmodeline = intern ("modeline"); + staticpro (&Qmodeline); + Qonly = intern ("only"); + staticpro (&Qonly); + Qwidth = intern ("width"); + staticpro (&Qwidth); + Qgeometry = intern ("geometry"); + staticpro (&Qgeometry); + Qicon_left = intern ("icon-left"); + staticpro (&Qicon_left); + Qicon_top = intern ("icon-top"); + staticpro (&Qicon_top); + Qleft = intern ("left"); + staticpro (&Qleft); + Qright = intern ("right"); + staticpro (&Qright); + Quser_position = intern ("user-position"); + staticpro (&Quser_position); + Quser_size = intern ("user-size"); + staticpro (&Quser_size); + Qwindow_id = intern ("window-id"); + staticpro (&Qwindow_id); +#ifdef HAVE_X_WINDOWS + Qouter_window_id = intern ("outer-window-id"); + staticpro (&Qouter_window_id); +#endif + Qparent_id = intern ("parent-id"); + staticpro (&Qparent_id); + Qx = intern ("x"); + staticpro (&Qx); + Qw32 = intern ("w32"); + staticpro (&Qw32); + Qpc = intern ("pc"); + staticpro (&Qpc); + Qmac = intern ("mac"); + staticpro (&Qmac); + Qvisible = intern ("visible"); + staticpro (&Qvisible); + Qbuffer_predicate = intern ("buffer-predicate"); + staticpro (&Qbuffer_predicate); + Qbuffer_list = intern ("buffer-list"); + staticpro (&Qbuffer_list); + Qdisplay_type = intern ("display-type"); + staticpro (&Qdisplay_type); + Qbackground_mode = intern ("background-mode"); + staticpro (&Qbackground_mode); + Qtty_color_mode = intern ("tty-color-mode"); + staticpro (&Qtty_color_mode); + + Qface_set_after_frame_default = intern ("face-set-after-frame-default"); + staticpro (&Qface_set_after_frame_default); + + Qfullwidth = intern ("fullwidth"); + staticpro (&Qfullwidth); + Qfullheight = intern ("fullheight"); + staticpro (&Qfullheight); + Qfullboth = intern ("fullboth"); + staticpro (&Qfullboth); + Qx_resource_name = intern ("x-resource-name"); + staticpro (&Qx_resource_name); + + Qx_frame_parameter = intern ("x-frame-parameter"); + staticpro (&Qx_frame_parameter); + + { + int i; + + for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++) + { + Lisp_Object v = intern (frame_parms[i].name); + if (frame_parms[i].variable) + { + *frame_parms[i].variable = v; + staticpro (frame_parms[i].variable); + } + Fput (v, Qx_frame_parameter, make_number (i)); + } + } + +#ifdef HAVE_WINDOW_SYSTEM + DEFVAR_LISP ("x-resource-name", &Vx_resource_name, + doc: /* The name Emacs uses to look up X resources. +`x-get-resource' uses this as the first component of the instance name +when requesting resource values. +Emacs initially sets `x-resource-name' to the name under which Emacs +was invoked, or to the value specified with the `-name' or `-rn' +switches, if present. + +It may be useful to bind this variable locally around a call +to `x-get-resource'. See also the variable `x-resource-class'. */); + Vx_resource_name = Qnil; + + DEFVAR_LISP ("x-resource-class", &Vx_resource_class, + doc: /* The class Emacs uses to look up X resources. +`x-get-resource' uses this as the first component of the instance class +when requesting resource values. + +Emacs initially sets `x-resource-class' to "Emacs". + +Setting this variable permanently is not a reasonable thing to do, +but binding this variable locally around a call to `x-get-resource' +is a reasonable practice. See also the variable `x-resource-name'. */); + Vx_resource_class = build_string (EMACS_CLASS); +#endif + + DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist, + doc: /* Alist of default values for frame creation. +These may be set in your init file, like this: + (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)) +These override values given in window system configuration data, + including X Windows' defaults database. +For values specific to the first Emacs frame, see `initial-frame-alist'. +For values specific to the separate minibuffer frame, see + `minibuffer-frame-alist'. +The `menu-bar-lines' element of the list controls whether new frames + have menu bars; `menu-bar-mode' works by altering this element. +Setting this variable does not affect existing frames, only new ones. */); + Vdefault_frame_alist = Qnil; + + DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars, + doc: /* Default position of scroll bars on this window-system. */); +#ifdef HAVE_WINDOW_SYSTEM +#if defined(HAVE_NTGUI) || defined(HAVE_CARBON) + /* MS-Windows has scroll bars on the right by default. */ + Vdefault_frame_scroll_bars = Qright; +#else + Vdefault_frame_scroll_bars = Qleft; +#endif +#else + Vdefault_frame_scroll_bars = Qnil; +#endif + + Qinhibit_default_face_x_resources + = intern ("inhibit-default-face-x-resources"); + staticpro (&Qinhibit_default_face_x_resources); + + DEFVAR_LISP ("terminal-frame", &Vterminal_frame, + doc: /* The initial frame-object, which represents Emacs's stdout. */); + + DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, + doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */); + Vemacs_iconified = Qnil; + + DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function, + doc: /* If non-nil, function to transform normal value of `mouse-position'. +`mouse-position' calls this function, passing its usual return value as +argument, and returns whatever this function returns. +This abnormal hook exists for the benefit of packages like `xt-mouse.el' +which need to do mouse handling at the Lisp level. */); + Vmouse_position_function = Qnil; + + DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight, + doc: /* If non-nil, clickable text is highlighted when mouse is over it. +If the value is an integer, highlighting is only shown after moving the +mouse, while keyboard input turns off the highlight even when the mouse +is over the clickable text. However, the mouse shape still indicates +when the mouse is over clickable text. */); + Vmouse_highlight = Qt; + + DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions, + doc: /* Functions to be run before deleting a frame. +The functions are run with one arg, the frame to be deleted. +See `delete-frame'. */); + Vdelete_frame_functions = Qnil; + + DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, + doc: /* Minibufferless frames use this frame's minibuffer. + +Emacs cannot create minibufferless frames unless this is set to an +appropriate surrogate. + +Emacs consults this variable only when creating minibufferless +frames; once the frame is created, it sticks with its assigned +minibuffer, no matter what this variable is set to. This means that +this variable doesn't necessarily say anything meaningful about the +current set of frames, or where the minibuffer is currently being +displayed. + +This variable is local to the current terminal and cannot be buffer-local. */); + + staticpro (&Vframe_list); + + defsubr (&Sactive_minibuffer_window); + defsubr (&Sframep); + defsubr (&Sframe_live_p); + defsubr (&Smake_terminal_frame); + defsubr (&Shandle_switch_frame); + defsubr (&Signore_event); + defsubr (&Sselect_frame); + defsubr (&Sselected_frame); + defsubr (&Swindow_frame); + defsubr (&Sframe_root_window); + defsubr (&Sframe_first_window); + defsubr (&Sframe_selected_window); + defsubr (&Sset_frame_selected_window); + defsubr (&Sframe_list); + defsubr (&Snext_frame); + defsubr (&Sprevious_frame); + defsubr (&Sdelete_frame); + defsubr (&Smouse_position); + defsubr (&Smouse_pixel_position); + defsubr (&Sset_mouse_position); + defsubr (&Sset_mouse_pixel_position); +#if 0 + defsubr (&Sframe_configuration); + defsubr (&Srestore_frame_configuration); +#endif + defsubr (&Smake_frame_visible); + defsubr (&Smake_frame_invisible); + defsubr (&Siconify_frame); + defsubr (&Sframe_visible_p); + defsubr (&Svisible_frame_list); + defsubr (&Sraise_frame); + defsubr (&Slower_frame); + defsubr (&Sredirect_frame_focus); + defsubr (&Sframe_focus); + defsubr (&Sframe_parameters); + defsubr (&Sframe_parameter); + defsubr (&Smodify_frame_parameters); + defsubr (&Sframe_char_height); + defsubr (&Sframe_char_width); + defsubr (&Sframe_pixel_height); + defsubr (&Sframe_pixel_width); + defsubr (&Sset_frame_height); + defsubr (&Sset_frame_width); + defsubr (&Sset_frame_size); + defsubr (&Sset_frame_position); + +#ifdef HAVE_WINDOW_SYSTEM + defsubr (&Sx_get_resource); + defsubr (&Sx_parse_geometry); +#endif + +} + +/* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039 + (do not change this comment) */