1/* Generic frame functions. 2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 3 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4 5This file is part of GNU Emacs. 6 7GNU Emacs is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU Emacs is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU Emacs; see the file COPYING. If not, write to 19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20Boston, MA 02110-1301, USA. */ 21 22#include <config.h> 23 24#include <stdio.h> 25#include "lisp.h" 26#include "charset.h" 27#ifdef HAVE_X_WINDOWS 28#include "xterm.h" 29#endif 30#ifdef WINDOWSNT 31#include "w32term.h" 32#endif 33#ifdef MAC_OS 34#include "macterm.h" 35#endif 36#include "buffer.h" 37/* These help us bind and responding to switch-frame events. */ 38#include "commands.h" 39#include "keyboard.h" 40#include "frame.h" 41#ifdef HAVE_WINDOW_SYSTEM 42#include "fontset.h" 43#endif 44#include "blockinput.h" 45#include "termhooks.h" 46#include "dispextern.h" 47#include "window.h" 48#ifdef MSDOS 49#include "msdos.h" 50#include "dosfns.h" 51#endif 52 53 54#ifdef HAVE_WINDOW_SYSTEM 55 56/* The name we're using in resource queries. Most often "emacs". */ 57 58Lisp_Object Vx_resource_name; 59 60/* The application class we're using in resource queries. 61 Normally "Emacs". */ 62 63Lisp_Object Vx_resource_class; 64 65#endif 66 67Lisp_Object Qframep, Qframe_live_p; 68Lisp_Object Qicon, Qmodeline; 69Lisp_Object Qonly; 70Lisp_Object Qx, Qw32, Qmac, Qpc; 71Lisp_Object Qvisible; 72Lisp_Object Qdisplay_type; 73Lisp_Object Qbackground_mode; 74 75Lisp_Object Qx_frame_parameter; 76Lisp_Object Qx_resource_name; 77 78/* Frame parameters (set or reported). */ 79 80Lisp_Object Qauto_raise, Qauto_lower; 81Lisp_Object Qborder_color, Qborder_width; 82Lisp_Object Qcursor_color, Qcursor_type; 83Lisp_Object Qgeometry; /* Not used */ 84Lisp_Object Qheight, Qwidth; 85Lisp_Object Qleft, Qright; 86Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; 87Lisp_Object Qinternal_border_width; 88Lisp_Object Qmouse_color; 89Lisp_Object Qminibuffer; 90Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; 91Lisp_Object Qvisibility; 92Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; 93Lisp_Object Qscreen_gamma; 94Lisp_Object Qline_spacing; 95Lisp_Object Quser_position, Quser_size; 96Lisp_Object Qwait_for_wm; 97Lisp_Object Qwindow_id; 98#ifdef HAVE_X_WINDOWS 99Lisp_Object Qouter_window_id; 100#endif 101Lisp_Object Qparent_id; 102Lisp_Object Qtitle, Qname; 103Lisp_Object Qunsplittable; 104Lisp_Object Qmenu_bar_lines, Qtool_bar_lines; 105Lisp_Object Qleft_fringe, Qright_fringe; 106Lisp_Object Qbuffer_predicate, Qbuffer_list; 107Lisp_Object Qtty_color_mode; 108 109Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth; 110 111Lisp_Object Qinhibit_face_set_after_frame_default; 112Lisp_Object Qface_set_after_frame_default; 113 114 115Lisp_Object Vterminal_frame; 116Lisp_Object Vdefault_frame_alist; 117Lisp_Object Vdefault_frame_scroll_bars; 118Lisp_Object Vmouse_position_function; 119Lisp_Object Vmouse_highlight; 120Lisp_Object Vdelete_frame_functions; 121 122static void 123set_menu_bar_lines_1 (window, n) 124 Lisp_Object window; 125 int n; 126{ 127 struct window *w = XWINDOW (window); 128 129 XSETFASTINT (w->last_modified, 0); 130 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); 131 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); 132 133 if (INTEGERP (w->orig_top_line)) 134 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n); 135 if (INTEGERP (w->orig_total_lines)) 136 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n); 137 138 /* Handle just the top child in a vertical split. */ 139 if (!NILP (w->vchild)) 140 set_menu_bar_lines_1 (w->vchild, n); 141 142 /* Adjust all children in a horizontal split. */ 143 for (window = w->hchild; !NILP (window); window = w->next) 144 { 145 w = XWINDOW (window); 146 set_menu_bar_lines_1 (window, n); 147 } 148} 149 150void 151set_menu_bar_lines (f, value, oldval) 152 struct frame *f; 153 Lisp_Object value, oldval; 154{ 155 int nlines; 156 int olines = FRAME_MENU_BAR_LINES (f); 157 158 /* Right now, menu bars don't work properly in minibuf-only frames; 159 most of the commands try to apply themselves to the minibuffer 160 frame itself, and get an error because you can't switch buffers 161 in or split the minibuffer window. */ 162 if (FRAME_MINIBUF_ONLY_P (f)) 163 return; 164 165 if (INTEGERP (value)) 166 nlines = XINT (value); 167 else 168 nlines = 0; 169 170 if (nlines != olines) 171 { 172 windows_or_buffers_changed++; 173 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 174 FRAME_MENU_BAR_LINES (f) = nlines; 175 set_menu_bar_lines_1 (f->root_window, nlines - olines); 176 adjust_glyphs (f); 177 } 178} 179 180Lisp_Object Vemacs_iconified; 181Lisp_Object Vframe_list; 182 183struct x_output tty_display; 184 185extern Lisp_Object Vminibuffer_list; 186extern Lisp_Object get_minibuffer (); 187extern Lisp_Object Fhandle_switch_frame (); 188extern Lisp_Object Fredirect_frame_focus (); 189extern Lisp_Object x_get_focus_frame (); 190 191DEFUN ("framep", Fframep, Sframep, 1, 1, 0, 192 doc: /* Return non-nil if OBJECT is a frame. 193Value is t for a termcap frame (a character-only terminal), 194`x' for an Emacs frame that is really an X window, 195`w32' for an Emacs frame that is a window on MS-Windows display, 196`mac' for an Emacs frame on a Macintosh display, 197`pc' for a direct-write MS-DOS frame. 198See also `frame-live-p'. */) 199 (object) 200 Lisp_Object object; 201{ 202 if (!FRAMEP (object)) 203 return Qnil; 204 switch (XFRAME (object)->output_method) 205 { 206 case output_termcap: 207 return Qt; 208 case output_x_window: 209 return Qx; 210 case output_w32: 211 return Qw32; 212 case output_msdos_raw: 213 return Qpc; 214 case output_mac: 215 return Qmac; 216 default: 217 abort (); 218 } 219} 220 221DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0, 222 doc: /* Return non-nil if OBJECT is a frame which has not been deleted. 223Value is nil if OBJECT is not a live frame. If object is a live 224frame, the return value indicates what sort of output device it is 225displayed on. See the documentation of `framep' for possible 226return values. */) 227 (object) 228 Lisp_Object object; 229{ 230 return ((FRAMEP (object) 231 && FRAME_LIVE_P (XFRAME (object))) 232 ? Fframep (object) 233 : Qnil); 234} 235 236struct frame * 237make_frame (mini_p) 238 int mini_p; 239{ 240 Lisp_Object frame; 241 register struct frame *f; 242 register Lisp_Object root_window; 243 register Lisp_Object mini_window; 244 245 f = allocate_frame (); 246 XSETFRAME (frame, f); 247 248 f->desired_matrix = 0; 249 f->current_matrix = 0; 250 f->desired_pool = 0; 251 f->current_pool = 0; 252 f->glyphs_initialized_p = 0; 253 f->decode_mode_spec_buffer = 0; 254 f->visible = 0; 255 f->async_visible = 0; 256 f->output_data.nothing = 0; 257 f->iconified = 0; 258 f->async_iconified = 0; 259 f->wants_modeline = 1; 260 f->auto_raise = 0; 261 f->auto_lower = 0; 262 f->no_split = 0; 263 f->garbaged = 1; 264 f->has_minibuffer = mini_p; 265 f->focus_frame = Qnil; 266 f->explicit_name = 0; 267 f->can_have_scroll_bars = 0; 268 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 269 f->param_alist = Qnil; 270 f->scroll_bars = Qnil; 271 f->condemned_scroll_bars = Qnil; 272 f->face_alist = Qnil; 273 f->face_cache = NULL; 274 f->menu_bar_items = Qnil; 275 f->menu_bar_vector = Qnil; 276 f->menu_bar_items_used = 0; 277 f->buffer_predicate = Qnil; 278 f->buffer_list = Qnil; 279#ifdef MULTI_KBOARD 280 f->kboard = initial_kboard; 281#endif 282 f->namebuf = 0; 283 f->title = Qnil; 284 f->menu_bar_window = Qnil; 285 f->tool_bar_window = Qnil; 286 f->tool_bar_items = Qnil; 287 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil; 288 f->n_tool_bar_items = 0; 289 f->left_fringe_width = f->right_fringe_width = 0; 290 f->fringe_cols = 0; 291 f->scroll_bar_actual_width = 0; 292 f->border_width = 0; 293 f->internal_border_width = 0; 294 f->column_width = 1; /* !FRAME_WINDOW_P value */ 295 f->line_height = 1; /* !FRAME_WINDOW_P value */ 296 f->x_pixels_diff = f->y_pixels_diff = 0; 297#ifdef HAVE_WINDOW_SYSTEM 298 f->want_fullscreen = FULLSCREEN_NONE; 299#endif 300 f->size_hint_flags = 0; 301 f->win_gravity = 0; 302 303 root_window = make_window (); 304 if (mini_p) 305 { 306 mini_window = make_window (); 307 XWINDOW (root_window)->next = mini_window; 308 XWINDOW (mini_window)->prev = root_window; 309 XWINDOW (mini_window)->mini_p = Qt; 310 XWINDOW (mini_window)->frame = frame; 311 f->minibuffer_window = mini_window; 312 } 313 else 314 { 315 mini_window = Qnil; 316 XWINDOW (root_window)->next = Qnil; 317 f->minibuffer_window = Qnil; 318 } 319 320 XWINDOW (root_window)->frame = frame; 321 322 /* 10 is arbitrary, 323 just so that there is "something there." 324 Correct size will be set up later with change_frame_size. */ 325 326 SET_FRAME_COLS (f, 10); 327 FRAME_LINES (f) = 10; 328 329 XSETFASTINT (XWINDOW (root_window)->total_cols, 10); 330 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10)); 331 332 if (mini_p) 333 { 334 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10); 335 XSETFASTINT (XWINDOW (mini_window)->top_line, 9); 336 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1); 337 } 338 339 /* Choose a buffer for the frame's root window. */ 340 { 341 Lisp_Object buf; 342 343 XWINDOW (root_window)->buffer = Qt; 344 buf = Fcurrent_buffer (); 345 /* If buf is a 'hidden' buffer (i.e. one whose name starts with 346 a space), try to find another one. */ 347 if (SREF (Fbuffer_name (buf), 0) == ' ') 348 buf = Fother_buffer (buf, Qnil, Qnil); 349 350 /* Use set_window_buffer, not Fset_window_buffer, and don't let 351 hooks be run by it. The reason is that the whole frame/window 352 arrangement is not yet fully intialized at this point. Windows 353 don't have the right size, glyph matrices aren't initialized 354 etc. Running Lisp functions at this point surely ends in a 355 SEGV. */ 356 set_window_buffer (root_window, buf, 0, 0); 357 f->buffer_list = Fcons (buf, Qnil); 358 } 359 360 if (mini_p) 361 { 362 XWINDOW (mini_window)->buffer = Qt; 363 set_window_buffer (mini_window, 364 (NILP (Vminibuffer_list) 365 ? get_minibuffer (0) 366 : Fcar (Vminibuffer_list)), 367 0, 0); 368 } 369 370 f->root_window = root_window; 371 f->selected_window = root_window; 372 /* Make sure this window seems more recently used than 373 a newly-created, never-selected window. */ 374 ++window_select_count; 375 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count); 376 377 f->default_face_done_p = 0; 378 379 return f; 380} 381 382#ifdef HAVE_WINDOW_SYSTEM 383/* Make a frame using a separate minibuffer window on another frame. 384 MINI_WINDOW is the minibuffer window to use. nil means use the 385 default (the global minibuffer). */ 386 387struct frame * 388make_frame_without_minibuffer (mini_window, kb, display) 389 register Lisp_Object mini_window; 390 KBOARD *kb; 391 Lisp_Object display; 392{ 393 register struct frame *f; 394 struct gcpro gcpro1; 395 396 if (!NILP (mini_window)) 397 CHECK_LIVE_WINDOW (mini_window); 398 399#ifdef MULTI_KBOARD 400 if (!NILP (mini_window) 401 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb) 402 error ("Frame and minibuffer must be on the same display"); 403#endif 404 405 /* Make a frame containing just a root window. */ 406 f = make_frame (0); 407 408 if (NILP (mini_window)) 409 { 410 /* Use default-minibuffer-frame if possible. */ 411 if (!FRAMEP (kb->Vdefault_minibuffer_frame) 412 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))) 413 { 414 Lisp_Object frame_dummy; 415 416 XSETFRAME (frame_dummy, f); 417 GCPRO1 (frame_dummy); 418 /* If there's no minibuffer frame to use, create one. */ 419 kb->Vdefault_minibuffer_frame = 420 call1 (intern ("make-initial-minibuffer-frame"), display); 421 UNGCPRO; 422 } 423 424 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window; 425 } 426 427 f->minibuffer_window = mini_window; 428 429 /* Make the chosen minibuffer window display the proper minibuffer, 430 unless it is already showing a minibuffer. */ 431 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list))) 432 Fset_window_buffer (mini_window, 433 (NILP (Vminibuffer_list) 434 ? get_minibuffer (0) 435 : Fcar (Vminibuffer_list)), Qnil); 436 return f; 437} 438 439/* Make a frame containing only a minibuffer window. */ 440 441struct frame * 442make_minibuffer_frame () 443{ 444 /* First make a frame containing just a root window, no minibuffer. */ 445 446 register struct frame *f = make_frame (0); 447 register Lisp_Object mini_window; 448 register Lisp_Object frame; 449 450 XSETFRAME (frame, f); 451 452 f->auto_raise = 0; 453 f->auto_lower = 0; 454 f->no_split = 1; 455 f->wants_modeline = 0; 456 f->has_minibuffer = 1; 457 458 /* Now label the root window as also being the minibuffer. 459 Avoid infinite looping on the window chain by marking next pointer 460 as nil. */ 461 462 mini_window = f->minibuffer_window = f->root_window; 463 XWINDOW (mini_window)->mini_p = Qt; 464 XWINDOW (mini_window)->next = Qnil; 465 XWINDOW (mini_window)->prev = Qnil; 466 XWINDOW (mini_window)->frame = frame; 467 468 /* Put the proper buffer in that window. */ 469 470 Fset_window_buffer (mini_window, 471 (NILP (Vminibuffer_list) 472 ? get_minibuffer (0) 473 : Fcar (Vminibuffer_list)), Qnil); 474 return f; 475} 476#endif /* HAVE_WINDOW_SYSTEM */ 477 478/* Construct a frame that refers to the terminal (stdin and stdout). */ 479 480static int terminal_frame_count; 481 482struct frame * 483make_terminal_frame () 484{ 485 register struct frame *f; 486 Lisp_Object frame; 487 char name[20]; 488 489#ifdef MULTI_KBOARD 490 if (!initial_kboard) 491 { 492 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); 493 init_kboard (initial_kboard); 494 initial_kboard->next_kboard = all_kboards; 495 all_kboards = initial_kboard; 496 } 497#endif 498 499 /* The first call must initialize Vframe_list. */ 500 if (! (NILP (Vframe_list) || CONSP (Vframe_list))) 501 Vframe_list = Qnil; 502 503 f = make_frame (1); 504 505 XSETFRAME (frame, f); 506 Vframe_list = Fcons (frame, Vframe_list); 507 508 terminal_frame_count++; 509 sprintf (name, "F%d", terminal_frame_count); 510 f->name = build_string (name); 511 512 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */ 513 f->async_visible = 1; /* Don't let visible be cleared later. */ 514#ifdef MSDOS 515 f->output_data.x = &the_only_x_display; 516 if (!inhibit_window_system 517 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)) 518 || XFRAME (selected_frame)->output_method == output_msdos_raw)) 519 { 520 f->output_method = output_msdos_raw; 521 /* This initialization of foreground and background pixels is 522 only important for the initial frame created in temacs. If 523 we don't do that, we get black background and foreground in 524 the dumped Emacs because the_only_x_display is a static 525 variable, hence it is born all-zeroes, and zero is the code 526 for the black color. Other frames all inherit their pixels 527 from what's already in the_only_x_display. */ 528 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))) 529 && f->output_data.x->background_pixel == 0 530 && f->output_data.x->foreground_pixel == 0) 531 { 532 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR; 533 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR; 534 } 535 } 536 else 537 f->output_method = output_termcap; 538#else 539#ifdef WINDOWSNT 540 f->output_method = output_termcap; 541 f->output_data.x = &tty_display; 542#else 543#ifdef MAC_OS8 544 make_mac_terminal_frame (f); 545#else 546 f->output_data.x = &tty_display; 547#ifdef CANNOT_DUMP 548 FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR; 549 FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR; 550#endif 551#endif /* MAC_OS8 */ 552#endif /* WINDOWSNT */ 553#endif /* MSDOS */ 554 555 if (!noninteractive) 556 init_frame_faces (f); 557 558 return f; 559} 560 561DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, 562 1, 1, 0, 563 doc: /* Create an additional terminal frame. 564You can create multiple frames on a text-only terminal in this way. 565Only the selected terminal frame is actually displayed. 566This function takes one argument, an alist specifying frame parameters. 567In practice, generally you don't need to specify any parameters. 568Note that changing the size of one terminal frame automatically affects all. */) 569 (parms) 570 Lisp_Object parms; 571{ 572 struct frame *f; 573 Lisp_Object frame, tem; 574 struct frame *sf = SELECTED_FRAME (); 575 576#ifdef MSDOS 577 if (sf->output_method != output_msdos_raw 578 && sf->output_method != output_termcap) 579 abort (); 580#else /* not MSDOS */ 581 582#ifdef MAC_OS 583 if (sf->output_method != output_mac) 584 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame"); 585#else 586 if (sf->output_method != output_termcap) 587 error ("Not using an ASCII terminal now; cannot make a new ASCII frame"); 588#endif 589#endif /* not MSDOS */ 590 591 f = make_terminal_frame (); 592 593 change_frame_size (f, FRAME_LINES (sf), 594 FRAME_COLS (sf), 0, 0, 0); 595 adjust_glyphs (f); 596 calculate_costs (f); 597 XSETFRAME (frame, f); 598 Fmodify_frame_parameters (frame, Vdefault_frame_alist); 599 Fmodify_frame_parameters (frame, parms); 600 601 /* Make the frame face alist be frame-specific, so that each 602 frame could change its face definitions independently. */ 603 f->face_alist = Fcopy_alist (sf->face_alist); 604 /* Simple Fcopy_alist isn't enough, because we need the contents of 605 the vectors which are the CDRs of associations in face_alist to 606 be copied as well. */ 607 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem)) 608 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem)))); 609 return frame; 610} 611 612 613/* Perform the switch to frame FRAME. 614 615 If FRAME is a switch-frame event `(switch-frame FRAME1)', use 616 FRAME1 as frame. 617 618 If TRACK is non-zero and the frame that currently has the focus 619 redirects its focus to the selected frame, redirect that focused 620 frame's focus to FRAME instead. 621 622 FOR_DELETION non-zero means that the selected frame is being 623 deleted, which includes the possibility that the frame's display 624 is dead. */ 625 626Lisp_Object 627do_switch_frame (frame, track, for_deletion) 628 Lisp_Object frame; 629 int track, for_deletion; 630{ 631 struct frame *sf = SELECTED_FRAME (); 632 633 /* If FRAME is a switch-frame event, extract the frame we should 634 switch to. */ 635 if (CONSP (frame) 636 && EQ (XCAR (frame), Qswitch_frame) 637 && CONSP (XCDR (frame))) 638 frame = XCAR (XCDR (frame)); 639 640 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for 641 a switch-frame event to arrive after a frame is no longer live, 642 especially when deleting the initial frame during startup. */ 643 CHECK_FRAME (frame); 644 if (! FRAME_LIVE_P (XFRAME (frame))) 645 return Qnil; 646 647 if (sf == XFRAME (frame)) 648 return frame; 649 650 /* This is too greedy; it causes inappropriate focus redirection 651 that's hard to get rid of. */ 652#if 0 653 /* If a frame's focus has been redirected toward the currently 654 selected frame, we should change the redirection to point to the 655 newly selected frame. This means that if the focus is redirected 656 from a minibufferless frame to a surrogate minibuffer frame, we 657 can use `other-window' to switch between all the frames using 658 that minibuffer frame, and the focus redirection will follow us 659 around. */ 660 if (track) 661 { 662 Lisp_Object tail; 663 664 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 665 { 666 Lisp_Object focus; 667 668 if (!FRAMEP (XCAR (tail))) 669 abort (); 670 671 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail))); 672 673 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ()) 674 Fredirect_frame_focus (XCAR (tail), frame); 675 } 676 } 677#else /* ! 0 */ 678 /* Instead, apply it only to the frame we're pointing to. */ 679#ifdef HAVE_WINDOW_SYSTEM 680 if (track && FRAME_WINDOW_P (XFRAME (frame))) 681 { 682 Lisp_Object focus, xfocus; 683 684 xfocus = x_get_focus_frame (XFRAME (frame)); 685 if (FRAMEP (xfocus)) 686 { 687 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus)); 688 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ()) 689 Fredirect_frame_focus (xfocus, frame); 690 } 691 } 692#endif /* HAVE_X_WINDOWS */ 693#endif /* ! 0 */ 694 695 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) 696 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); 697 698 selected_frame = frame; 699 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) 700 last_nonminibuf_frame = XFRAME (selected_frame); 701 702 Fselect_window (XFRAME (frame)->selected_window, Qnil); 703 704#ifndef WINDOWSNT 705 /* Make sure to switch the tty color mode to that of the newly 706 selected frame. */ 707 sf = SELECTED_FRAME (); 708 if (FRAME_TERMCAP_P (sf)) 709 { 710 Lisp_Object color_mode_spec, color_mode; 711 712 color_mode_spec = assq_no_quit (Qtty_color_mode, sf->param_alist); 713 if (CONSP (color_mode_spec)) 714 color_mode = XCDR (color_mode_spec); 715 else 716 color_mode = make_number (0); 717 set_tty_color_mode (sf, color_mode); 718 } 719#endif /* !WINDOWSNT */ 720 721 /* We want to make sure that the next event generates a frame-switch 722 event to the appropriate frame. This seems kludgy to me, but 723 before you take it out, make sure that evaluating something like 724 (select-window (frame-root-window (new-frame))) doesn't end up 725 with your typing being interpreted in the new frame instead of 726 the one you're actually typing in. */ 727 internal_last_event_frame = Qnil; 728 729 return frame; 730} 731 732DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 1, "e", 733 doc: /* Select the frame FRAME. 734Subsequent editing commands apply to its selected window. 735The selection of FRAME lasts until the next time the user does 736something to select a different frame, or until the next time this 737function is called. If you are using a window system, the previously 738selected frame may be restored as the selected frame after return to 739the command loop, because it still may have the window system's input 740focus. On a text-only terminal, the next redisplay will display FRAME. 741 742This function returns FRAME, or nil if FRAME has been deleted. */) 743 (frame) 744 Lisp_Object frame; 745{ 746 return do_switch_frame (frame, 1, 0); 747} 748 749 750DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e", 751 doc: /* Handle a switch-frame event EVENT. 752Switch-frame events are usually bound to this function. 753A switch-frame event tells Emacs that the window manager has requested 754that the user's events be directed to the frame mentioned in the event. 755This function selects the selected window of the frame of EVENT. 756 757If EVENT is frame object, handle it as if it were a switch-frame event 758to that frame. */) 759 (event) 760 Lisp_Object event; 761{ 762 /* Preserve prefix arg that the command loop just cleared. */ 763 current_kboard->Vprefix_arg = Vcurrent_prefix_arg; 764 call1 (Vrun_hooks, Qmouse_leave_buffer_hook); 765 return do_switch_frame (event, 0, 0); 766} 767 768DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, 769 doc: /* Return the frame that is now selected. */) 770 () 771{ 772 return selected_frame; 773} 774 775DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, 776 doc: /* Return the frame object that window WINDOW is on. */) 777 (window) 778 Lisp_Object window; 779{ 780 CHECK_LIVE_WINDOW (window); 781 return XWINDOW (window)->frame; 782} 783 784DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0, 785 doc: /* Returns the topmost, leftmost window of FRAME. 786If omitted, FRAME defaults to the currently selected frame. */) 787 (frame) 788 Lisp_Object frame; 789{ 790 Lisp_Object w; 791 792 if (NILP (frame)) 793 w = SELECTED_FRAME ()->root_window; 794 else 795 { 796 CHECK_LIVE_FRAME (frame); 797 w = XFRAME (frame)->root_window; 798 } 799 while (NILP (XWINDOW (w)->buffer)) 800 { 801 if (! NILP (XWINDOW (w)->hchild)) 802 w = XWINDOW (w)->hchild; 803 else if (! NILP (XWINDOW (w)->vchild)) 804 w = XWINDOW (w)->vchild; 805 else 806 abort (); 807 } 808 return w; 809} 810 811DEFUN ("active-minibuffer-window", Factive_minibuffer_window, 812 Sactive_minibuffer_window, 0, 0, 0, 813 doc: /* Return the currently active minibuffer window, or nil if none. */) 814 () 815{ 816 return minibuf_level ? minibuf_window : Qnil; 817} 818 819DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0, 820 doc: /* Returns the root-window of FRAME. 821If omitted, FRAME defaults to the currently selected frame. */) 822 (frame) 823 Lisp_Object frame; 824{ 825 Lisp_Object window; 826 827 if (NILP (frame)) 828 window = SELECTED_FRAME ()->root_window; 829 else 830 { 831 CHECK_LIVE_FRAME (frame); 832 window = XFRAME (frame)->root_window; 833 } 834 835 return window; 836} 837 838DEFUN ("frame-selected-window", Fframe_selected_window, 839 Sframe_selected_window, 0, 1, 0, 840 doc: /* Return the selected window of frame object FRAME. 841If omitted, FRAME defaults to the currently selected frame. */) 842 (frame) 843 Lisp_Object frame; 844{ 845 Lisp_Object window; 846 847 if (NILP (frame)) 848 window = SELECTED_FRAME ()->selected_window; 849 else 850 { 851 CHECK_LIVE_FRAME (frame); 852 window = XFRAME (frame)->selected_window; 853 } 854 855 return window; 856} 857 858DEFUN ("set-frame-selected-window", Fset_frame_selected_window, 859 Sset_frame_selected_window, 2, 2, 0, 860 doc: /* Set the selected window of frame object FRAME to WINDOW. 861Return WINDOW. 862If FRAME is nil, the selected frame is used. 863If FRAME is the selected frame, this makes WINDOW the selected window. */) 864 (frame, window) 865 Lisp_Object frame, window; 866{ 867 if (NILP (frame)) 868 frame = selected_frame; 869 870 CHECK_LIVE_FRAME (frame); 871 CHECK_LIVE_WINDOW (window); 872 873 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window)))) 874 error ("In `set-frame-selected-window', WINDOW is not on FRAME"); 875 876 if (EQ (frame, selected_frame)) 877 return Fselect_window (window, Qnil); 878 879 return XFRAME (frame)->selected_window = window; 880} 881 882DEFUN ("frame-list", Fframe_list, Sframe_list, 883 0, 0, 0, 884 doc: /* Return a list of all frames. */) 885 () 886{ 887 Lisp_Object frames; 888 frames = Fcopy_sequence (Vframe_list); 889#ifdef HAVE_WINDOW_SYSTEM 890 if (FRAMEP (tip_frame)) 891 frames = Fdelq (tip_frame, frames); 892#endif 893 return frames; 894} 895 896/* Return the next frame in the frame list after FRAME. 897 If MINIBUF is nil, exclude minibuffer-only frames. 898 If MINIBUF is a window, include only its own frame 899 and any frame now using that window as the minibuffer. 900 If MINIBUF is `visible', include all visible frames. 901 If MINIBUF is 0, include all visible and iconified frames. 902 Otherwise, include all frames. */ 903 904static Lisp_Object 905next_frame (frame, minibuf) 906 Lisp_Object frame; 907 Lisp_Object minibuf; 908{ 909 Lisp_Object tail; 910 int passed = 0; 911 912 /* There must always be at least one frame in Vframe_list. */ 913 if (! CONSP (Vframe_list)) 914 abort (); 915 916 /* If this frame is dead, it won't be in Vframe_list, and we'll loop 917 forever. Forestall that. */ 918 CHECK_LIVE_FRAME (frame); 919 920 while (1) 921 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 922 { 923 Lisp_Object f; 924 925 f = XCAR (tail); 926 927 if (passed 928 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) 929 { 930 /* Decide whether this frame is eligible to be returned. */ 931 932 /* If we've looped all the way around without finding any 933 eligible frames, return the original frame. */ 934 if (EQ (f, frame)) 935 return f; 936 937 /* Let minibuf decide if this frame is acceptable. */ 938 if (NILP (minibuf)) 939 { 940 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) 941 return f; 942 } 943 else if (EQ (minibuf, Qvisible)) 944 { 945 FRAME_SAMPLE_VISIBILITY (XFRAME (f)); 946 if (FRAME_VISIBLE_P (XFRAME (f))) 947 return f; 948 } 949 else if (INTEGERP (minibuf) && XINT (minibuf) == 0) 950 { 951 FRAME_SAMPLE_VISIBILITY (XFRAME (f)); 952 if (FRAME_VISIBLE_P (XFRAME (f)) 953 || FRAME_ICONIFIED_P (XFRAME (f))) 954 return f; 955 } 956 else if (WINDOWP (minibuf)) 957 { 958 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) 959 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) 960 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), 961 FRAME_FOCUS_FRAME (XFRAME (f)))) 962 return f; 963 } 964 else 965 return f; 966 } 967 968 if (EQ (frame, f)) 969 passed++; 970 } 971} 972 973/* Return the previous frame in the frame list before FRAME. 974 If MINIBUF is nil, exclude minibuffer-only frames. 975 If MINIBUF is a window, include only its own frame 976 and any frame now using that window as the minibuffer. 977 If MINIBUF is `visible', include all visible frames. 978 If MINIBUF is 0, include all visible and iconified frames. 979 Otherwise, include all frames. */ 980 981static Lisp_Object 982prev_frame (frame, minibuf) 983 Lisp_Object frame; 984 Lisp_Object minibuf; 985{ 986 Lisp_Object tail; 987 Lisp_Object prev; 988 989 /* There must always be at least one frame in Vframe_list. */ 990 if (! CONSP (Vframe_list)) 991 abort (); 992 993 prev = Qnil; 994 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 995 { 996 Lisp_Object f; 997 998 f = XCAR (tail); 999 if (!FRAMEP (f)) 1000 abort (); 1001 1002 if (EQ (frame, f) && !NILP (prev)) 1003 return prev; 1004 1005 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) 1006 { 1007 /* Decide whether this frame is eligible to be returned, 1008 according to minibuf. */ 1009 if (NILP (minibuf)) 1010 { 1011 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) 1012 prev = f; 1013 } 1014 else if (WINDOWP (minibuf)) 1015 { 1016 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) 1017 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) 1018 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), 1019 FRAME_FOCUS_FRAME (XFRAME (f)))) 1020 prev = f; 1021 } 1022 else if (EQ (minibuf, Qvisible)) 1023 { 1024 FRAME_SAMPLE_VISIBILITY (XFRAME (f)); 1025 if (FRAME_VISIBLE_P (XFRAME (f))) 1026 prev = f; 1027 } 1028 else if (XFASTINT (minibuf) == 0) 1029 { 1030 FRAME_SAMPLE_VISIBILITY (XFRAME (f)); 1031 if (FRAME_VISIBLE_P (XFRAME (f)) 1032 || FRAME_ICONIFIED_P (XFRAME (f))) 1033 prev = f; 1034 } 1035 else 1036 prev = f; 1037 } 1038 } 1039 1040 /* We've scanned the entire list. */ 1041 if (NILP (prev)) 1042 /* We went through the whole frame list without finding a single 1043 acceptable frame. Return the original frame. */ 1044 return frame; 1045 else 1046 /* There were no acceptable frames in the list before FRAME; otherwise, 1047 we would have returned directly from the loop. Since PREV is the last 1048 acceptable frame in the list, return it. */ 1049 return prev; 1050} 1051 1052 1053DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0, 1054 doc: /* Return the next frame in the frame list after FRAME. 1055It considers only frames on the same terminal as FRAME. 1056By default, skip minibuffer-only frames. 1057If omitted, FRAME defaults to the selected frame. 1058If optional argument MINIFRAME is nil, exclude minibuffer-only frames. 1059If MINIFRAME is a window, include only its own frame 1060and any frame now using that window as the minibuffer. 1061If MINIFRAME is `visible', include all visible frames. 1062If MINIFRAME is 0, include all visible and iconified frames. 1063Otherwise, include all frames. */) 1064 (frame, miniframe) 1065 Lisp_Object frame, miniframe; 1066{ 1067 if (NILP (frame)) 1068 frame = selected_frame; 1069 1070 CHECK_LIVE_FRAME (frame); 1071 return next_frame (frame, miniframe); 1072} 1073 1074DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0, 1075 doc: /* Return the previous frame in the frame list before FRAME. 1076It considers only frames on the same terminal as FRAME. 1077By default, skip minibuffer-only frames. 1078If omitted, FRAME defaults to the selected frame. 1079If optional argument MINIFRAME is nil, exclude minibuffer-only frames. 1080If MINIFRAME is a window, include only its own frame 1081and any frame now using that window as the minibuffer. 1082If MINIFRAME is `visible', include all visible frames. 1083If MINIFRAME is 0, include all visible and iconified frames. 1084Otherwise, include all frames. */) 1085 (frame, miniframe) 1086 Lisp_Object frame, miniframe; 1087{ 1088 if (NILP (frame)) 1089 frame = selected_frame; 1090 CHECK_LIVE_FRAME (frame); 1091 return prev_frame (frame, miniframe); 1092} 1093 1094/* Return 1 if it is ok to delete frame F; 1095 0 if all frames aside from F are invisible. 1096 (Exception: if F is the terminal frame, and we are using X, return 1.) */ 1097 1098int 1099other_visible_frames (f) 1100 FRAME_PTR f; 1101{ 1102 /* We know the selected frame is visible, 1103 so if F is some other frame, it can't be the sole visible one. */ 1104 if (f == SELECTED_FRAME ()) 1105 { 1106 Lisp_Object frames; 1107 int count = 0; 1108 1109 for (frames = Vframe_list; 1110 CONSP (frames); 1111 frames = XCDR (frames)) 1112 { 1113 Lisp_Object this; 1114 1115 this = XCAR (frames); 1116 /* Verify that the frame's window still exists 1117 and we can still talk to it. And note any recent change 1118 in visibility. */ 1119#ifdef HAVE_WINDOW_SYSTEM 1120 if (FRAME_WINDOW_P (XFRAME (this))) 1121 { 1122 x_sync (XFRAME (this)); 1123 FRAME_SAMPLE_VISIBILITY (XFRAME (this)); 1124 } 1125#endif 1126 1127 if (FRAME_VISIBLE_P (XFRAME (this)) 1128 || FRAME_ICONIFIED_P (XFRAME (this)) 1129 /* Allow deleting the terminal frame when at least 1130 one X frame exists! */ 1131 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f))) 1132 count++; 1133 } 1134 return count > 1; 1135 } 1136 return 1; 1137} 1138 1139DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "", 1140 doc: /* Delete FRAME, permanently eliminating it from use. 1141If omitted, FRAME defaults to the selected frame. 1142A frame may not be deleted if its minibuffer is used by other frames. 1143Normally, you may not delete a frame if all other frames are invisible, 1144but if the second optional argument FORCE is non-nil, you may do so. 1145 1146This function runs `delete-frame-functions' before actually deleting the 1147frame, unless the frame is a tooltip. 1148The functions are run with one arg, the frame to be deleted. */) 1149 (frame, force) 1150 Lisp_Object frame, force; 1151{ 1152 struct frame *f; 1153 struct frame *sf = SELECTED_FRAME (); 1154 int minibuffer_selected; 1155 1156 if (EQ (frame, Qnil)) 1157 { 1158 f = sf; 1159 XSETFRAME (frame, f); 1160 } 1161 else 1162 { 1163 CHECK_FRAME (frame); 1164 f = XFRAME (frame); 1165 } 1166 1167 if (! FRAME_LIVE_P (f)) 1168 return Qnil; 1169 1170 if (NILP (force) && !other_visible_frames (f) 1171#ifdef MAC_OS8 1172 /* Terminal frame deleted before any other visible frames are 1173 created. */ 1174 && strcmp (SDATA (f->name), "F1") != 0 1175#endif 1176 ) 1177 error ("Attempt to delete the sole visible or iconified frame"); 1178 1179#if 0 1180 /* This is a nice idea, but x_connection_closed needs to be able 1181 to delete the last frame, if it is gone. */ 1182 if (NILP (XCDR (Vframe_list))) 1183 error ("Attempt to delete the only frame"); 1184#endif 1185 1186 /* Does this frame have a minibuffer, and is it the surrogate 1187 minibuffer for any other frame? */ 1188 if (FRAME_HAS_MINIBUF_P (XFRAME (frame))) 1189 { 1190 Lisp_Object frames; 1191 1192 for (frames = Vframe_list; 1193 CONSP (frames); 1194 frames = XCDR (frames)) 1195 { 1196 Lisp_Object this; 1197 this = XCAR (frames); 1198 1199 if (! EQ (this, frame) 1200 && EQ (frame, 1201 WINDOW_FRAME (XWINDOW 1202 (FRAME_MINIBUF_WINDOW (XFRAME (this)))))) 1203 error ("Attempt to delete a surrogate minibuffer frame"); 1204 } 1205 } 1206 1207 /* Run `delete-frame-functions' unless frame is a tooltip. */ 1208 if (!NILP (Vrun_hooks) 1209 && NILP (Fframe_parameter (frame, intern ("tooltip")))) 1210 { 1211 Lisp_Object args[2]; 1212 args[0] = intern ("delete-frame-functions"); 1213 args[1] = frame; 1214 Frun_hook_with_args (2, args); 1215 } 1216 1217 minibuffer_selected = EQ (minibuf_window, selected_window); 1218 1219 /* Don't let the frame remain selected. */ 1220 if (f == sf) 1221 { 1222 Lisp_Object tail, frame1; 1223 1224 /* Look for another visible frame on the same terminal. */ 1225 frame1 = next_frame (frame, Qvisible); 1226 1227 /* If there is none, find *some* other frame. */ 1228 if (NILP (frame1) || EQ (frame1, frame)) 1229 { 1230 FOR_EACH_FRAME (tail, frame1) 1231 { 1232 if (! EQ (frame, frame1)) 1233 break; 1234 } 1235 } 1236 1237 do_switch_frame (frame1, 0, 1); 1238 sf = SELECTED_FRAME (); 1239 } 1240 1241 /* Don't allow minibuf_window to remain on a deleted frame. */ 1242 if (EQ (f->minibuffer_window, minibuf_window)) 1243 { 1244 Fset_window_buffer (sf->minibuffer_window, 1245 XWINDOW (minibuf_window)->buffer, Qnil); 1246 minibuf_window = sf->minibuffer_window; 1247 1248 /* If the dying minibuffer window was selected, 1249 select the new one. */ 1250 if (minibuffer_selected) 1251 Fselect_window (minibuf_window, Qnil); 1252 } 1253 1254 /* Don't let echo_area_window to remain on a deleted frame. */ 1255 if (EQ (f->minibuffer_window, echo_area_window)) 1256 echo_area_window = sf->minibuffer_window; 1257 1258 /* Clear any X selections for this frame. */ 1259#ifdef HAVE_X_WINDOWS 1260 if (FRAME_X_P (f)) 1261 x_clear_frame_selections (f); 1262#endif 1263#ifdef MAC_OS 1264 if (FRAME_MAC_P (f)) 1265 x_clear_frame_selections (f); 1266#endif 1267 1268 /* Free glyphs. 1269 This function must be called before the window tree of the 1270 frame is deleted because windows contain dynamically allocated 1271 memory. */ 1272 free_glyphs (f); 1273 1274 /* Mark all the windows that used to be on FRAME as deleted, and then 1275 remove the reference to them. */ 1276 delete_all_subwindows (XWINDOW (f->root_window)); 1277 f->root_window = Qnil; 1278 1279 Vframe_list = Fdelq (frame, Vframe_list); 1280 FRAME_SET_VISIBLE (f, 0); 1281 1282 if (f->namebuf) 1283 xfree (f->namebuf); 1284 if (f->decode_mode_spec_buffer) 1285 xfree (f->decode_mode_spec_buffer); 1286 if (FRAME_INSERT_COST (f)) 1287 xfree (FRAME_INSERT_COST (f)); 1288 if (FRAME_DELETEN_COST (f)) 1289 xfree (FRAME_DELETEN_COST (f)); 1290 if (FRAME_INSERTN_COST (f)) 1291 xfree (FRAME_INSERTN_COST (f)); 1292 if (FRAME_DELETE_COST (f)) 1293 xfree (FRAME_DELETE_COST (f)); 1294 if (FRAME_MESSAGE_BUF (f)) 1295 xfree (FRAME_MESSAGE_BUF (f)); 1296 1297 /* Since some events are handled at the interrupt level, we may get 1298 an event for f at any time; if we zero out the frame's display 1299 now, then we may trip up the event-handling code. Instead, we'll 1300 promise that the display of the frame must be valid until we have 1301 called the window-system-dependent frame destruction routine. */ 1302 1303 /* I think this should be done with a hook. */ 1304#ifdef HAVE_WINDOW_SYSTEM 1305 if (FRAME_WINDOW_P (f)) 1306 x_destroy_window (f); 1307#endif 1308 1309 f->output_data.nothing = 0; 1310 1311 /* If we've deleted the last_nonminibuf_frame, then try to find 1312 another one. */ 1313 if (f == last_nonminibuf_frame) 1314 { 1315 Lisp_Object frames; 1316 1317 last_nonminibuf_frame = 0; 1318 1319 for (frames = Vframe_list; 1320 CONSP (frames); 1321 frames = XCDR (frames)) 1322 { 1323 f = XFRAME (XCAR (frames)); 1324 if (!FRAME_MINIBUF_ONLY_P (f)) 1325 { 1326 last_nonminibuf_frame = f; 1327 break; 1328 } 1329 } 1330 } 1331 1332 /* If there's no other frame on the same kboard, get out of 1333 single-kboard state if we're in it for this kboard. */ 1334 { 1335 Lisp_Object frames; 1336 /* Some frame we found on the same kboard, or nil if there are none. */ 1337 Lisp_Object frame_on_same_kboard; 1338 1339 frame_on_same_kboard = Qnil; 1340 1341 for (frames = Vframe_list; 1342 CONSP (frames); 1343 frames = XCDR (frames)) 1344 { 1345 Lisp_Object this; 1346 struct frame *f1; 1347 1348 this = XCAR (frames); 1349 if (!FRAMEP (this)) 1350 abort (); 1351 f1 = XFRAME (this); 1352 1353 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)) 1354 frame_on_same_kboard = this; 1355 } 1356 1357 if (NILP (frame_on_same_kboard)) 1358 not_single_kboard_state (FRAME_KBOARD (f)); 1359 } 1360 1361 1362 /* If we've deleted this keyboard's default_minibuffer_frame, try to 1363 find another one. Prefer minibuffer-only frames, but also notice 1364 frames with other windows. */ 1365 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame)) 1366 { 1367 Lisp_Object frames; 1368 1369 /* The last frame we saw with a minibuffer, minibuffer-only or not. */ 1370 Lisp_Object frame_with_minibuf; 1371 /* Some frame we found on the same kboard, or nil if there are none. */ 1372 Lisp_Object frame_on_same_kboard; 1373 1374 frame_on_same_kboard = Qnil; 1375 frame_with_minibuf = Qnil; 1376 1377 for (frames = Vframe_list; 1378 CONSP (frames); 1379 frames = XCDR (frames)) 1380 { 1381 Lisp_Object this; 1382 struct frame *f1; 1383 1384 this = XCAR (frames); 1385 if (!FRAMEP (this)) 1386 abort (); 1387 f1 = XFRAME (this); 1388 1389 /* Consider only frames on the same kboard 1390 and only those with minibuffers. */ 1391 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1) 1392 && FRAME_HAS_MINIBUF_P (f1)) 1393 { 1394 frame_with_minibuf = this; 1395 if (FRAME_MINIBUF_ONLY_P (f1)) 1396 break; 1397 } 1398 1399 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)) 1400 frame_on_same_kboard = this; 1401 } 1402 1403 if (!NILP (frame_on_same_kboard)) 1404 { 1405 /* We know that there must be some frame with a minibuffer out 1406 there. If this were not true, all of the frames present 1407 would have to be minibufferless, which implies that at some 1408 point their minibuffer frames must have been deleted, but 1409 that is prohibited at the top; you can't delete surrogate 1410 minibuffer frames. */ 1411 if (NILP (frame_with_minibuf)) 1412 abort (); 1413 1414 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf; 1415 } 1416 else 1417 /* No frames left on this kboard--say no minibuffer either. */ 1418 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil; 1419 } 1420 1421 /* Cause frame titles to update--necessary if we now have just one frame. */ 1422 update_mode_lines = 1; 1423 1424 return Qnil; 1425} 1426 1427/* Return mouse position in character cell units. */ 1428 1429DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, 1430 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position. 1431The position is given in character cells, where (0, 0) is the 1432upper-left corner of the frame, X is the horizontal offset, and Y is 1433the vertical offset. 1434If Emacs is running on a mouseless terminal or hasn't been programmed 1435to read the mouse position, it returns the selected frame for FRAME 1436and nil for X and Y. 1437If `mouse-position-function' is non-nil, `mouse-position' calls it, 1438passing the normal return value to that function as an argument, 1439and returns whatever that function returns. */) 1440 () 1441{ 1442 FRAME_PTR f; 1443 Lisp_Object lispy_dummy; 1444 enum scroll_bar_part party_dummy; 1445 Lisp_Object x, y, retval; 1446 int col, row; 1447 unsigned long long_dummy; 1448 struct gcpro gcpro1; 1449 1450 f = SELECTED_FRAME (); 1451 x = y = Qnil; 1452 1453#ifdef HAVE_MOUSE 1454 /* It's okay for the hook to refrain from storing anything. */ 1455 if (mouse_position_hook) 1456 (*mouse_position_hook) (&f, -1, 1457 &lispy_dummy, &party_dummy, 1458 &x, &y, 1459 &long_dummy); 1460 if (! NILP (x)) 1461 { 1462 col = XINT (x); 1463 row = XINT (y); 1464 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1); 1465 XSETINT (x, col); 1466 XSETINT (y, row); 1467 } 1468#endif 1469 XSETFRAME (lispy_dummy, f); 1470 retval = Fcons (lispy_dummy, Fcons (x, y)); 1471 GCPRO1 (retval); 1472 if (!NILP (Vmouse_position_function)) 1473 retval = call1 (Vmouse_position_function, retval); 1474 RETURN_UNGCPRO (retval); 1475} 1476 1477DEFUN ("mouse-pixel-position", Fmouse_pixel_position, 1478 Smouse_pixel_position, 0, 0, 0, 1479 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position. 1480The position is given in pixel units, where (0, 0) is the 1481upper-left corner of the frame, X is the horizontal offset, and Y is 1482the vertical offset. 1483If Emacs is running on a mouseless terminal or hasn't been programmed 1484to read the mouse position, it returns the selected frame for FRAME 1485and nil for X and Y. */) 1486 () 1487{ 1488 FRAME_PTR f; 1489 Lisp_Object lispy_dummy; 1490 enum scroll_bar_part party_dummy; 1491 Lisp_Object x, y; 1492 unsigned long long_dummy; 1493 1494 f = SELECTED_FRAME (); 1495 x = y = Qnil; 1496 1497#ifdef HAVE_MOUSE 1498 /* It's okay for the hook to refrain from storing anything. */ 1499 if (mouse_position_hook) 1500 (*mouse_position_hook) (&f, -1, 1501 &lispy_dummy, &party_dummy, 1502 &x, &y, 1503 &long_dummy); 1504#endif 1505 XSETFRAME (lispy_dummy, f); 1506 return Fcons (lispy_dummy, Fcons (x, y)); 1507} 1508 1509DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0, 1510 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME. 1511Coordinates are relative to the frame, not a window, 1512so the coordinates of the top left character in the frame 1513may be nonzero due to left-hand scroll bars or the menu bar. 1514 1515The position is given in character cells, where (0, 0) is the 1516upper-left corner of the frame, X is the horizontal offset, and Y is 1517the vertical offset. 1518 1519This function is a no-op for an X frame that is not visible. 1520If you have just created a frame, you must wait for it to become visible 1521before calling this function on it, like this. 1522 (while (not (frame-visible-p frame)) (sleep-for .5)) */) 1523 (frame, x, y) 1524 Lisp_Object frame, x, y; 1525{ 1526 CHECK_LIVE_FRAME (frame); 1527 CHECK_NUMBER (x); 1528 CHECK_NUMBER (y); 1529 1530 /* I think this should be done with a hook. */ 1531#ifdef HAVE_WINDOW_SYSTEM 1532 if (FRAME_WINDOW_P (XFRAME (frame))) 1533 /* Warping the mouse will cause enternotify and focus events. */ 1534 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y)); 1535#else 1536#if defined (MSDOS) && defined (HAVE_MOUSE) 1537 if (FRAME_MSDOS_P (XFRAME (frame))) 1538 { 1539 Fselect_frame (frame); 1540 mouse_moveto (XINT (x), XINT (y)); 1541 } 1542#endif 1543#endif 1544 1545 return Qnil; 1546} 1547 1548DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position, 1549 Sset_mouse_pixel_position, 3, 3, 0, 1550 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME. 1551The position is given in pixels, where (0, 0) is the upper-left corner 1552of the frame, X is the horizontal offset, and Y is the vertical offset. 1553 1554Note, this is a no-op for an X frame that is not visible. 1555If you have just created a frame, you must wait for it to become visible 1556before calling this function on it, like this. 1557 (while (not (frame-visible-p frame)) (sleep-for .5)) */) 1558 (frame, x, y) 1559 Lisp_Object frame, x, y; 1560{ 1561 CHECK_LIVE_FRAME (frame); 1562 CHECK_NUMBER (x); 1563 CHECK_NUMBER (y); 1564 1565 /* I think this should be done with a hook. */ 1566#ifdef HAVE_WINDOW_SYSTEM 1567 if (FRAME_WINDOW_P (XFRAME (frame))) 1568 /* Warping the mouse will cause enternotify and focus events. */ 1569 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y)); 1570#else 1571#if defined (MSDOS) && defined (HAVE_MOUSE) 1572 if (FRAME_MSDOS_P (XFRAME (frame))) 1573 { 1574 Fselect_frame (frame); 1575 mouse_moveto (XINT (x), XINT (y)); 1576 } 1577#endif 1578#endif 1579 1580 return Qnil; 1581} 1582 1583static void make_frame_visible_1 P_ ((Lisp_Object)); 1584 1585DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible, 1586 0, 1, "", 1587 doc: /* Make the frame FRAME visible (assuming it is an X window). 1588If omitted, FRAME defaults to the currently selected frame. */) 1589 (frame) 1590 Lisp_Object frame; 1591{ 1592 if (NILP (frame)) 1593 frame = selected_frame; 1594 1595 CHECK_LIVE_FRAME (frame); 1596 1597 /* I think this should be done with a hook. */ 1598#ifdef HAVE_WINDOW_SYSTEM 1599 if (FRAME_WINDOW_P (XFRAME (frame))) 1600 { 1601 FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); 1602 x_make_frame_visible (XFRAME (frame)); 1603 } 1604#endif 1605 1606 make_frame_visible_1 (XFRAME (frame)->root_window); 1607 1608 /* Make menu bar update for the Buffers and Frames menus. */ 1609 windows_or_buffers_changed++; 1610 1611 return frame; 1612} 1613 1614/* Update the display_time slot of the buffers shown in WINDOW 1615 and all its descendents. */ 1616 1617static void 1618make_frame_visible_1 (window) 1619 Lisp_Object window; 1620{ 1621 struct window *w; 1622 1623 for (;!NILP (window); window = w->next) 1624 { 1625 w = XWINDOW (window); 1626 1627 if (!NILP (w->buffer)) 1628 XBUFFER (w->buffer)->display_time = Fcurrent_time (); 1629 1630 if (!NILP (w->vchild)) 1631 make_frame_visible_1 (w->vchild); 1632 if (!NILP (w->hchild)) 1633 make_frame_visible_1 (w->hchild); 1634 } 1635} 1636 1637DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible, 1638 0, 2, "", 1639 doc: /* Make the frame FRAME invisible (assuming it is an X window). 1640If omitted, FRAME defaults to the currently selected frame. 1641Normally you may not make FRAME invisible if all other frames are invisible, 1642but if the second optional argument FORCE is non-nil, you may do so. */) 1643 (frame, force) 1644 Lisp_Object frame, force; 1645{ 1646 if (NILP (frame)) 1647 frame = selected_frame; 1648 1649 CHECK_LIVE_FRAME (frame); 1650 1651 if (NILP (force) && !other_visible_frames (XFRAME (frame))) 1652 error ("Attempt to make invisible the sole visible or iconified frame"); 1653 1654#if 0 /* This isn't logically necessary, and it can do GC. */ 1655 /* Don't let the frame remain selected. */ 1656 if (EQ (frame, selected_frame)) 1657 do_switch_frame (next_frame (frame, Qt), 0, 0) 1658#endif 1659 1660 /* Don't allow minibuf_window to remain on a deleted frame. */ 1661 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1662 { 1663 struct frame *sf = XFRAME (selected_frame); 1664 Fset_window_buffer (sf->minibuffer_window, 1665 XWINDOW (minibuf_window)->buffer, Qnil); 1666 minibuf_window = sf->minibuffer_window; 1667 } 1668 1669 /* I think this should be done with a hook. */ 1670#ifdef HAVE_WINDOW_SYSTEM 1671 if (FRAME_WINDOW_P (XFRAME (frame))) 1672 x_make_frame_invisible (XFRAME (frame)); 1673#endif 1674 1675 /* Make menu bar update for the Buffers and Frames menus. */ 1676 windows_or_buffers_changed++; 1677 1678 return Qnil; 1679} 1680 1681DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame, 1682 0, 1, "", 1683 doc: /* Make the frame FRAME into an icon. 1684If omitted, FRAME defaults to the currently selected frame. */) 1685 (frame) 1686 Lisp_Object frame; 1687{ 1688 if (NILP (frame)) 1689 frame = selected_frame; 1690 1691 CHECK_LIVE_FRAME (frame); 1692 1693#if 0 /* This isn't logically necessary, and it can do GC. */ 1694 /* Don't let the frame remain selected. */ 1695 if (EQ (frame, selected_frame)) 1696 Fhandle_switch_frame (next_frame (frame, Qt)); 1697#endif 1698 1699 /* Don't allow minibuf_window to remain on a deleted frame. */ 1700 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1701 { 1702 struct frame *sf = XFRAME (selected_frame); 1703 Fset_window_buffer (sf->minibuffer_window, 1704 XWINDOW (minibuf_window)->buffer, Qnil); 1705 minibuf_window = sf->minibuffer_window; 1706 } 1707 1708 /* I think this should be done with a hook. */ 1709#ifdef HAVE_WINDOW_SYSTEM 1710 if (FRAME_WINDOW_P (XFRAME (frame))) 1711 x_iconify_frame (XFRAME (frame)); 1712#endif 1713 1714 /* Make menu bar update for the Buffers and Frames menus. */ 1715 windows_or_buffers_changed++; 1716 1717 return Qnil; 1718} 1719 1720DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p, 1721 1, 1, 0, 1722 doc: /* Return t if FRAME is now \"visible\" (actually in use for display). 1723A frame that is not \"visible\" is not updated and, if it works through 1724a window system, it may not show at all. 1725Return the symbol `icon' if frame is visible only as an icon. 1726 1727On a text-only terminal, all frames are considered visible, whether 1728they are currently being displayed or not, and this function returns t 1729for all frames. */) 1730 (frame) 1731 Lisp_Object frame; 1732{ 1733 CHECK_LIVE_FRAME (frame); 1734 1735 FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); 1736 1737 if (FRAME_VISIBLE_P (XFRAME (frame))) 1738 return Qt; 1739 if (FRAME_ICONIFIED_P (XFRAME (frame))) 1740 return Qicon; 1741 return Qnil; 1742} 1743 1744DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list, 1745 0, 0, 0, 1746 doc: /* Return a list of all frames now \"visible\" (being updated). */) 1747 () 1748{ 1749 Lisp_Object tail, frame; 1750 struct frame *f; 1751 Lisp_Object value; 1752 1753 value = Qnil; 1754 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1755 { 1756 frame = XCAR (tail); 1757 if (!FRAMEP (frame)) 1758 continue; 1759 f = XFRAME (frame); 1760 if (FRAME_VISIBLE_P (f)) 1761 value = Fcons (frame, value); 1762 } 1763 return value; 1764} 1765 1766 1767DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "", 1768 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps. 1769If FRAME is invisible or iconified, make it visible. 1770If you don't specify a frame, the selected frame is used. 1771If Emacs is displaying on an ordinary terminal or some other device which 1772doesn't support multiple overlapping frames, this function does nothing. */) 1773 (frame) 1774 Lisp_Object frame; 1775{ 1776 if (NILP (frame)) 1777 frame = selected_frame; 1778 1779 CHECK_LIVE_FRAME (frame); 1780 1781 /* Do like the documentation says. */ 1782 Fmake_frame_visible (frame); 1783 1784 if (frame_raise_lower_hook) 1785 (*frame_raise_lower_hook) (XFRAME (frame), 1); 1786 1787 return Qnil; 1788} 1789 1790/* Should we have a corresponding function called Flower_Power? */ 1791DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "", 1792 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it. 1793If you don't specify a frame, the selected frame is used. 1794If Emacs is displaying on an ordinary terminal or some other device which 1795doesn't support multiple overlapping frames, this function does nothing. */) 1796 (frame) 1797 Lisp_Object frame; 1798{ 1799 if (NILP (frame)) 1800 frame = selected_frame; 1801 1802 CHECK_LIVE_FRAME (frame); 1803 1804 if (frame_raise_lower_hook) 1805 (*frame_raise_lower_hook) (XFRAME (frame), 0); 1806 1807 return Qnil; 1808} 1809 1810 1811DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus, 1812 1, 2, 0, 1813 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME. 1814In other words, switch-frame events caused by events in FRAME will 1815request a switch to FOCUS-FRAME, and `last-event-frame' will be 1816FOCUS-FRAME after reading an event typed at FRAME. 1817 1818If FOCUS-FRAME is omitted or nil, any existing redirection is 1819cancelled, and the frame again receives its own keystrokes. 1820 1821Focus redirection is useful for temporarily redirecting keystrokes to 1822a surrogate minibuffer frame when a frame doesn't have its own 1823minibuffer window. 1824 1825A frame's focus redirection can be changed by `select-frame'. If frame 1826FOO is selected, and then a different frame BAR is selected, any 1827frames redirecting their focus to FOO are shifted to redirect their 1828focus to BAR. This allows focus redirection to work properly when the 1829user switches from one frame to another using `select-window'. 1830 1831This means that a frame whose focus is redirected to itself is treated 1832differently from a frame whose focus is redirected to nil; the former 1833is affected by `select-frame', while the latter is not. 1834 1835The redirection lasts until `redirect-frame-focus' is called to change it. */) 1836 (frame, focus_frame) 1837 Lisp_Object frame, focus_frame; 1838{ 1839 /* Note that we don't check for a live frame here. It's reasonable 1840 to redirect the focus of a frame you're about to delete, if you 1841 know what other frame should receive those keystrokes. */ 1842 CHECK_FRAME (frame); 1843 1844 if (! NILP (focus_frame)) 1845 CHECK_LIVE_FRAME (focus_frame); 1846 1847 XFRAME (frame)->focus_frame = focus_frame; 1848 1849 if (frame_rehighlight_hook) 1850 (*frame_rehighlight_hook) (XFRAME (frame)); 1851 1852 return Qnil; 1853} 1854 1855 1856DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0, 1857 doc: /* Return the frame to which FRAME's keystrokes are currently being sent. 1858This returns nil if FRAME's focus is not redirected. 1859See `redirect-frame-focus'. */) 1860 (frame) 1861 Lisp_Object frame; 1862{ 1863 CHECK_LIVE_FRAME (frame); 1864 1865 return FRAME_FOCUS_FRAME (XFRAME (frame)); 1866} 1867 1868 1869 1870/* Return the value of frame parameter PROP in frame FRAME. */ 1871 1872Lisp_Object 1873get_frame_param (frame, prop) 1874 register struct frame *frame; 1875 Lisp_Object prop; 1876{ 1877 register Lisp_Object tem; 1878 1879 tem = Fassq (prop, frame->param_alist); 1880 if (EQ (tem, Qnil)) 1881 return tem; 1882 return Fcdr (tem); 1883} 1884 1885/* Return the buffer-predicate of the selected frame. */ 1886 1887Lisp_Object 1888frame_buffer_predicate (frame) 1889 Lisp_Object frame; 1890{ 1891 return XFRAME (frame)->buffer_predicate; 1892} 1893 1894/* Return the buffer-list of the selected frame. */ 1895 1896Lisp_Object 1897frame_buffer_list (frame) 1898 Lisp_Object frame; 1899{ 1900 return XFRAME (frame)->buffer_list; 1901} 1902 1903/* Set the buffer-list of the selected frame. */ 1904 1905void 1906set_frame_buffer_list (frame, list) 1907 Lisp_Object frame, list; 1908{ 1909 XFRAME (frame)->buffer_list = list; 1910} 1911 1912/* Discard BUFFER from the buffer-list of each frame. */ 1913 1914void 1915frames_discard_buffer (buffer) 1916 Lisp_Object buffer; 1917{ 1918 Lisp_Object frame, tail; 1919 1920 FOR_EACH_FRAME (tail, frame) 1921 { 1922 XFRAME (frame)->buffer_list 1923 = Fdelq (buffer, XFRAME (frame)->buffer_list); 1924 } 1925} 1926 1927/* Modify the alist in *ALISTPTR to associate PROP with VAL. 1928 If the alist already has an element for PROP, we change it. */ 1929 1930void 1931store_in_alist (alistptr, prop, val) 1932 Lisp_Object *alistptr, val; 1933 Lisp_Object prop; 1934{ 1935 register Lisp_Object tem; 1936 1937 tem = Fassq (prop, *alistptr); 1938 if (EQ (tem, Qnil)) 1939 *alistptr = Fcons (Fcons (prop, val), *alistptr); 1940 else 1941 Fsetcdr (tem, val); 1942} 1943 1944static int 1945frame_name_fnn_p (str, len) 1946 char *str; 1947 int len; 1948{ 1949 if (len > 1 && str[0] == 'F') 1950 { 1951 char *end_ptr; 1952 1953 strtol (str + 1, &end_ptr, 10); 1954 1955 if (end_ptr == str + len) 1956 return 1; 1957 } 1958 return 0; 1959} 1960 1961/* Set the name of the terminal frame. Also used by MSDOS frames. 1962 Modeled after x_set_name which is used for WINDOW frames. */ 1963 1964static void 1965set_term_frame_name (f, name) 1966 struct frame *f; 1967 Lisp_Object name; 1968{ 1969 f->explicit_name = ! NILP (name); 1970 1971 /* If NAME is nil, set the name to F<num>. */ 1972 if (NILP (name)) 1973 { 1974 char namebuf[20]; 1975 1976 /* Check for no change needed in this very common case 1977 before we do any consing. */ 1978 if (frame_name_fnn_p (SDATA (f->name), 1979 SBYTES (f->name))) 1980 return; 1981 1982 terminal_frame_count++; 1983 sprintf (namebuf, "F%d", terminal_frame_count); 1984 name = build_string (namebuf); 1985 } 1986 else 1987 { 1988 CHECK_STRING (name); 1989 1990 /* Don't change the name if it's already NAME. */ 1991 if (! NILP (Fstring_equal (name, f->name))) 1992 return; 1993 1994 /* Don't allow the user to set the frame name to F<num>, so it 1995 doesn't clash with the names we generate for terminal frames. */ 1996 if (frame_name_fnn_p (SDATA (name), SBYTES (name))) 1997 error ("Frame names of the form F<num> are usurped by Emacs"); 1998 } 1999 2000 f->name = name; 2001 update_mode_lines = 1; 2002} 2003 2004void 2005store_frame_param (f, prop, val) 2006 struct frame *f; 2007 Lisp_Object prop, val; 2008{ 2009 register Lisp_Object old_alist_elt; 2010 2011 /* The buffer-alist parameter is stored in a special place and is 2012 not in the alist. */ 2013 if (EQ (prop, Qbuffer_list)) 2014 { 2015 f->buffer_list = val; 2016 return; 2017 } 2018 2019 /* If PROP is a symbol which is supposed to have frame-local values, 2020 and it is set up based on this frame, switch to the global 2021 binding. That way, we can create or alter the frame-local binding 2022 without messing up the symbol's status. */ 2023 if (SYMBOLP (prop)) 2024 { 2025 Lisp_Object valcontents; 2026 valcontents = SYMBOL_VALUE (prop); 2027 if ((BUFFER_LOCAL_VALUEP (valcontents) 2028 || SOME_BUFFER_LOCAL_VALUEP (valcontents)) 2029 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame 2030 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f) 2031 swap_in_global_binding (prop); 2032 } 2033 2034#ifndef WINDOWSNT 2035 /* The tty color mode needs to be set before the frame's parameter 2036 alist is updated with the new value, because set_tty_color_mode 2037 wants to look at the old mode. */ 2038 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)) 2039 set_tty_color_mode (f, val); 2040#endif 2041 2042 /* Update the frame parameter alist. */ 2043 old_alist_elt = Fassq (prop, f->param_alist); 2044 if (EQ (old_alist_elt, Qnil)) 2045 f->param_alist = Fcons (Fcons (prop, val), f->param_alist); 2046 else 2047 Fsetcdr (old_alist_elt, val); 2048 2049 /* Update some other special parameters in their special places 2050 in addition to the alist. */ 2051 2052 if (EQ (prop, Qbuffer_predicate)) 2053 f->buffer_predicate = val; 2054 2055 if (! FRAME_WINDOW_P (f)) 2056 { 2057 if (EQ (prop, Qmenu_bar_lines)) 2058 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f))); 2059 else if (EQ (prop, Qname)) 2060 set_term_frame_name (f, val); 2061 } 2062 2063 if (EQ (prop, Qminibuffer) && WINDOWP (val)) 2064 { 2065 if (! MINI_WINDOW_P (XWINDOW (val))) 2066 error ("Surrogate minibuffer windows must be minibuffer windows"); 2067 2068 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)) 2069 && !EQ (val, f->minibuffer_window)) 2070 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer"); 2071 2072 /* Install the chosen minibuffer window, with proper buffer. */ 2073 f->minibuffer_window = val; 2074 } 2075} 2076 2077DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0, 2078 doc: /* Return the parameters-alist of frame FRAME. 2079It is a list of elements of the form (PARM . VALUE), where PARM is a symbol. 2080The meaningful PARMs depend on the kind of frame. 2081If FRAME is omitted, return information on the currently selected frame. */) 2082 (frame) 2083 Lisp_Object frame; 2084{ 2085 Lisp_Object alist; 2086 FRAME_PTR f; 2087 int height, width; 2088 struct gcpro gcpro1; 2089 2090 if (NILP (frame)) 2091 frame = selected_frame; 2092 2093 CHECK_FRAME (frame); 2094 f = XFRAME (frame); 2095 2096 if (!FRAME_LIVE_P (f)) 2097 return Qnil; 2098 2099 alist = Fcopy_alist (f->param_alist); 2100 GCPRO1 (alist); 2101 2102 if (!FRAME_WINDOW_P (f)) 2103 { 2104 int fg = FRAME_FOREGROUND_PIXEL (f); 2105 int bg = FRAME_BACKGROUND_PIXEL (f); 2106 Lisp_Object elt; 2107 2108 /* If the frame's parameter alist says the colors are 2109 unspecified and reversed, take the frame's background pixel 2110 for foreground and vice versa. */ 2111 elt = Fassq (Qforeground_color, alist); 2112 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt))) 2113 { 2114 if (strncmp (SDATA (XCDR (elt)), 2115 unspecified_bg, 2116 SCHARS (XCDR (elt))) == 0) 2117 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg)); 2118 else if (strncmp (SDATA (XCDR (elt)), 2119 unspecified_fg, 2120 SCHARS (XCDR (elt))) == 0) 2121 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg)); 2122 } 2123 else 2124 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg)); 2125 elt = Fassq (Qbackground_color, alist); 2126 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt))) 2127 { 2128 if (strncmp (SDATA (XCDR (elt)), 2129 unspecified_fg, 2130 SCHARS (XCDR (elt))) == 0) 2131 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg)); 2132 else if (strncmp (SDATA (XCDR (elt)), 2133 unspecified_bg, 2134 SCHARS (XCDR (elt))) == 0) 2135 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg)); 2136 } 2137 else 2138 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg)); 2139 store_in_alist (&alist, intern ("font"), 2140 build_string (FRAME_MSDOS_P (f) 2141 ? "ms-dos" 2142 : FRAME_W32_P (f) ? "w32term" 2143 :"tty")); 2144 } 2145 store_in_alist (&alist, Qname, f->name); 2146 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); 2147 store_in_alist (&alist, Qheight, make_number (height)); 2148 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); 2149 store_in_alist (&alist, Qwidth, make_number (width)); 2150 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil)); 2151 store_in_alist (&alist, Qminibuffer, 2152 (! FRAME_HAS_MINIBUF_P (f) ? Qnil 2153 : FRAME_MINIBUF_ONLY_P (f) ? Qonly 2154 : FRAME_MINIBUF_WINDOW (f))); 2155 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil)); 2156 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame)); 2157 2158 /* I think this should be done with a hook. */ 2159#ifdef HAVE_WINDOW_SYSTEM 2160 if (FRAME_WINDOW_P (f)) 2161 x_report_frame_params (f, &alist); 2162 else 2163#endif 2164 { 2165 /* This ought to be correct in f->param_alist for an X frame. */ 2166 Lisp_Object lines; 2167 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f)); 2168 store_in_alist (&alist, Qmenu_bar_lines, lines); 2169 } 2170 2171 UNGCPRO; 2172 return alist; 2173} 2174 2175 2176DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0, 2177 doc: /* Return FRAME's value for parameter PARAMETER. 2178If FRAME is nil, describe the currently selected frame. */) 2179 (frame, parameter) 2180 Lisp_Object frame, parameter; 2181{ 2182 struct frame *f; 2183 Lisp_Object value; 2184 2185 if (NILP (frame)) 2186 frame = selected_frame; 2187 else 2188 CHECK_FRAME (frame); 2189 CHECK_SYMBOL (parameter); 2190 2191 f = XFRAME (frame); 2192 value = Qnil; 2193 2194 if (FRAME_LIVE_P (f)) 2195 { 2196 /* Avoid consing in frequent cases. */ 2197 if (EQ (parameter, Qname)) 2198 value = f->name; 2199#ifdef HAVE_X_WINDOWS 2200 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f)) 2201 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element); 2202#endif /* HAVE_X_WINDOWS */ 2203 else if (EQ (parameter, Qbackground_color) 2204 || EQ (parameter, Qforeground_color)) 2205 { 2206 value = Fassq (parameter, f->param_alist); 2207 if (CONSP (value)) 2208 { 2209 value = XCDR (value); 2210 /* Fframe_parameters puts the actual fg/bg color names, 2211 even if f->param_alist says otherwise. This is 2212 important when param_alist's notion of colors is 2213 "unspecified". We need to do the same here. */ 2214 if (STRINGP (value) && !FRAME_WINDOW_P (f)) 2215 { 2216 const char *color_name; 2217 EMACS_INT csz; 2218 2219 if (EQ (parameter, Qbackground_color)) 2220 { 2221 color_name = SDATA (value); 2222 csz = SCHARS (value); 2223 if (strncmp (color_name, unspecified_bg, csz) == 0) 2224 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)); 2225 else if (strncmp (color_name, unspecified_fg, csz) == 0) 2226 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)); 2227 } 2228 else if (EQ (parameter, Qforeground_color)) 2229 { 2230 color_name = SDATA (value); 2231 csz = SCHARS (value); 2232 if (strncmp (color_name, unspecified_fg, csz) == 0) 2233 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)); 2234 else if (strncmp (color_name, unspecified_bg, csz) == 0) 2235 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)); 2236 } 2237 } 2238 } 2239 else 2240 value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); 2241 } 2242 else if (EQ (parameter, Qdisplay_type) 2243 || EQ (parameter, Qbackground_mode)) 2244 value = Fcdr (Fassq (parameter, f->param_alist)); 2245 else 2246 value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); 2247 } 2248 2249 return value; 2250} 2251 2252 2253DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 2254 Smodify_frame_parameters, 2, 2, 0, 2255 doc: /* Modify the parameters of frame FRAME according to ALIST. 2256If FRAME is nil, it defaults to the selected frame. 2257ALIST is an alist of parameters to change and their new values. 2258Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol. 2259The meaningful PARMs depend on the kind of frame. 2260Undefined PARMs are ignored, but stored in the frame's parameter list 2261so that `frame-parameters' will return them. 2262 2263The value of frame parameter FOO can also be accessed 2264as a frame-local binding for the variable FOO, if you have 2265enabled such bindings for that variable with `make-variable-frame-local'. */) 2266 (frame, alist) 2267 Lisp_Object frame, alist; 2268{ 2269 FRAME_PTR f; 2270 register Lisp_Object tail, prop, val; 2271 2272 if (EQ (frame, Qnil)) 2273 frame = selected_frame; 2274 CHECK_LIVE_FRAME (frame); 2275 f = XFRAME (frame); 2276 2277 /* I think this should be done with a hook. */ 2278#ifdef HAVE_WINDOW_SYSTEM 2279 if (FRAME_WINDOW_P (f)) 2280 x_set_frame_parameters (f, alist); 2281 else 2282#endif 2283#ifdef MSDOS 2284 if (FRAME_MSDOS_P (f)) 2285 IT_set_frame_parameters (f, alist); 2286 else 2287#endif 2288 2289 { 2290 int length = XINT (Flength (alist)); 2291 int i; 2292 Lisp_Object *parms 2293 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); 2294 Lisp_Object *values 2295 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); 2296 2297 /* Extract parm names and values into those vectors. */ 2298 2299 i = 0; 2300 for (tail = alist; CONSP (tail); tail = Fcdr (tail)) 2301 { 2302 Lisp_Object elt; 2303 2304 elt = Fcar (tail); 2305 parms[i] = Fcar (elt); 2306 values[i] = Fcdr (elt); 2307 i++; 2308 } 2309 2310 /* Now process them in reverse of specified order. */ 2311 for (i--; i >= 0; i--) 2312 { 2313 prop = parms[i]; 2314 val = values[i]; 2315 store_frame_param (f, prop, val); 2316 2317 /* Changing the background color might change the background 2318 mode, so that we have to load new defface specs. 2319 Call frame-set-background-mode to do that. */ 2320 if (EQ (prop, Qbackground_color)) 2321 call1 (Qframe_set_background_mode, frame); 2322 } 2323 } 2324 2325 return Qnil; 2326} 2327 2328DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height, 2329 0, 1, 0, 2330 doc: /* Height in pixels of a line in the font in frame FRAME. 2331If FRAME is omitted, the selected frame is used. 2332For a terminal frame, the value is always 1. */) 2333 (frame) 2334 Lisp_Object frame; 2335{ 2336 struct frame *f; 2337 2338 if (NILP (frame)) 2339 frame = selected_frame; 2340 CHECK_FRAME (frame); 2341 f = XFRAME (frame); 2342 2343#ifdef HAVE_WINDOW_SYSTEM 2344 if (FRAME_WINDOW_P (f)) 2345 return make_number (x_char_height (f)); 2346 else 2347#endif 2348 return make_number (1); 2349} 2350 2351 2352DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width, 2353 0, 1, 0, 2354 doc: /* Width in pixels of characters in the font in frame FRAME. 2355If FRAME is omitted, the selected frame is used. 2356On a graphical screen, the width is the standard width of the default font. 2357For a terminal screen, the value is always 1. */) 2358 (frame) 2359 Lisp_Object frame; 2360{ 2361 struct frame *f; 2362 2363 if (NILP (frame)) 2364 frame = selected_frame; 2365 CHECK_FRAME (frame); 2366 f = XFRAME (frame); 2367 2368#ifdef HAVE_WINDOW_SYSTEM 2369 if (FRAME_WINDOW_P (f)) 2370 return make_number (x_char_width (f)); 2371 else 2372#endif 2373 return make_number (1); 2374} 2375 2376DEFUN ("frame-pixel-height", Fframe_pixel_height, 2377 Sframe_pixel_height, 0, 1, 0, 2378 doc: /* Return a FRAME's height in pixels. 2379This counts only the height available for text lines, 2380not menu bars on window-system Emacs frames. 2381For a terminal frame, the result really gives the height in characters. 2382If FRAME is omitted, the selected frame is used. */) 2383 (frame) 2384 Lisp_Object frame; 2385{ 2386 struct frame *f; 2387 2388 if (NILP (frame)) 2389 frame = selected_frame; 2390 CHECK_FRAME (frame); 2391 f = XFRAME (frame); 2392 2393#ifdef HAVE_WINDOW_SYSTEM 2394 if (FRAME_WINDOW_P (f)) 2395 return make_number (x_pixel_height (f)); 2396 else 2397#endif 2398 return make_number (FRAME_LINES (f)); 2399} 2400 2401DEFUN ("frame-pixel-width", Fframe_pixel_width, 2402 Sframe_pixel_width, 0, 1, 0, 2403 doc: /* Return FRAME's width in pixels. 2404For a terminal frame, the result really gives the width in characters. 2405If FRAME is omitted, the selected frame is used. */) 2406 (frame) 2407 Lisp_Object frame; 2408{ 2409 struct frame *f; 2410 2411 if (NILP (frame)) 2412 frame = selected_frame; 2413 CHECK_FRAME (frame); 2414 f = XFRAME (frame); 2415 2416#ifdef HAVE_WINDOW_SYSTEM 2417 if (FRAME_WINDOW_P (f)) 2418 return make_number (x_pixel_width (f)); 2419 else 2420#endif 2421 return make_number (FRAME_COLS (f)); 2422} 2423 2424DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0, 2425 doc: /* Specify that the frame FRAME has LINES lines. 2426Optional third arg non-nil means that redisplay should use LINES lines 2427but that the idea of the actual height of the frame should not be changed. */) 2428 (frame, lines, pretend) 2429 Lisp_Object frame, lines, pretend; 2430{ 2431 register struct frame *f; 2432 2433 CHECK_NUMBER (lines); 2434 if (NILP (frame)) 2435 frame = selected_frame; 2436 CHECK_LIVE_FRAME (frame); 2437 f = XFRAME (frame); 2438 2439 /* I think this should be done with a hook. */ 2440#ifdef HAVE_WINDOW_SYSTEM 2441 if (FRAME_WINDOW_P (f)) 2442 { 2443 if (XINT (lines) != FRAME_LINES (f)) 2444 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines)); 2445 do_pending_window_change (0); 2446 } 2447 else 2448#endif 2449 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0); 2450 return Qnil; 2451} 2452 2453DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0, 2454 doc: /* Specify that the frame FRAME has COLS columns. 2455Optional third arg non-nil means that redisplay should use COLS columns 2456but that the idea of the actual width of the frame should not be changed. */) 2457 (frame, cols, pretend) 2458 Lisp_Object frame, cols, pretend; 2459{ 2460 register struct frame *f; 2461 CHECK_NUMBER (cols); 2462 if (NILP (frame)) 2463 frame = selected_frame; 2464 CHECK_LIVE_FRAME (frame); 2465 f = XFRAME (frame); 2466 2467 /* I think this should be done with a hook. */ 2468#ifdef HAVE_WINDOW_SYSTEM 2469 if (FRAME_WINDOW_P (f)) 2470 { 2471 if (XINT (cols) != FRAME_COLS (f)) 2472 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f)); 2473 do_pending_window_change (0); 2474 } 2475 else 2476#endif 2477 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0); 2478 return Qnil; 2479} 2480 2481DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, 2482 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */) 2483 (frame, cols, rows) 2484 Lisp_Object frame, cols, rows; 2485{ 2486 register struct frame *f; 2487 2488 CHECK_LIVE_FRAME (frame); 2489 CHECK_NUMBER (cols); 2490 CHECK_NUMBER (rows); 2491 f = XFRAME (frame); 2492 2493 /* I think this should be done with a hook. */ 2494#ifdef HAVE_WINDOW_SYSTEM 2495 if (FRAME_WINDOW_P (f)) 2496 { 2497 if (XINT (rows) != FRAME_LINES (f) 2498 || XINT (cols) != FRAME_COLS (f) 2499 || f->new_text_lines || f->new_text_cols) 2500 x_set_window_size (f, 1, XINT (cols), XINT (rows)); 2501 do_pending_window_change (0); 2502 } 2503 else 2504#endif 2505 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0); 2506 2507 return Qnil; 2508} 2509 2510DEFUN ("set-frame-position", Fset_frame_position, 2511 Sset_frame_position, 3, 3, 0, 2512 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET. 2513This is actually the position of the upper left corner of the frame. 2514Negative values for XOFFSET or YOFFSET are interpreted relative to 2515the rightmost or bottommost possible position (that stays within the screen). */) 2516 (frame, xoffset, yoffset) 2517 Lisp_Object frame, xoffset, yoffset; 2518{ 2519 register struct frame *f; 2520 2521 CHECK_LIVE_FRAME (frame); 2522 CHECK_NUMBER (xoffset); 2523 CHECK_NUMBER (yoffset); 2524 f = XFRAME (frame); 2525 2526 /* I think this should be done with a hook. */ 2527#ifdef HAVE_WINDOW_SYSTEM 2528 if (FRAME_WINDOW_P (f)) 2529 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1); 2530#endif 2531 2532 return Qt; 2533} 2534 2535 2536/*********************************************************************** 2537 Frame Parameters 2538 ***********************************************************************/ 2539 2540/* Connect the frame-parameter names for X frames 2541 to the ways of passing the parameter values to the window system. 2542 2543 The name of a parameter, as a Lisp symbol, 2544 has an `x-frame-parameter' property which is an integer in Lisp 2545 that is an index in this table. */ 2546 2547struct frame_parm_table { 2548 char *name; 2549 Lisp_Object *variable; 2550}; 2551 2552static struct frame_parm_table frame_parms[] = 2553{ 2554 {"auto-raise", &Qauto_raise}, 2555 {"auto-lower", &Qauto_lower}, 2556 {"background-color", 0}, 2557 {"border-color", &Qborder_color}, 2558 {"border-width", &Qborder_width}, 2559 {"cursor-color", &Qcursor_color}, 2560 {"cursor-type", &Qcursor_type}, 2561 {"font", 0}, 2562 {"foreground-color", 0}, 2563 {"icon-name", &Qicon_name}, 2564 {"icon-type", &Qicon_type}, 2565 {"internal-border-width", &Qinternal_border_width}, 2566 {"menu-bar-lines", &Qmenu_bar_lines}, 2567 {"mouse-color", &Qmouse_color}, 2568 {"name", &Qname}, 2569 {"scroll-bar-width", &Qscroll_bar_width}, 2570 {"title", &Qtitle}, 2571 {"unsplittable", &Qunsplittable}, 2572 {"vertical-scroll-bars", &Qvertical_scroll_bars}, 2573 {"visibility", &Qvisibility}, 2574 {"tool-bar-lines", &Qtool_bar_lines}, 2575 {"scroll-bar-foreground", &Qscroll_bar_foreground}, 2576 {"scroll-bar-background", &Qscroll_bar_background}, 2577 {"screen-gamma", &Qscreen_gamma}, 2578 {"line-spacing", &Qline_spacing}, 2579 {"left-fringe", &Qleft_fringe}, 2580 {"right-fringe", &Qright_fringe}, 2581 {"wait-for-wm", &Qwait_for_wm}, 2582 {"fullscreen", &Qfullscreen}, 2583}; 2584 2585#ifdef HAVE_WINDOW_SYSTEM 2586 2587extern Lisp_Object Qbox; 2588extern Lisp_Object Qtop; 2589 2590/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the 2591 wanted positions of the WM window (not Emacs window). 2592 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs 2593 window (FRAME_X_WINDOW). 2594 */ 2595 2596void 2597x_fullscreen_adjust (f, width, height, top_pos, left_pos) 2598 struct frame *f; 2599 int *width; 2600 int *height; 2601 int *top_pos; 2602 int *left_pos; 2603{ 2604 int newwidth = FRAME_COLS (f); 2605 int newheight = FRAME_LINES (f); 2606 2607 *top_pos = f->top_pos; 2608 *left_pos = f->left_pos; 2609 2610 if (f->want_fullscreen & FULLSCREEN_HEIGHT) 2611 { 2612 int ph; 2613 2614 ph = FRAME_X_DISPLAY_INFO (f)->height; 2615 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); 2616 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff; 2617 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); 2618 *top_pos = 0; 2619 } 2620 2621 if (f->want_fullscreen & FULLSCREEN_WIDTH) 2622 { 2623 int pw; 2624 2625 pw = FRAME_X_DISPLAY_INFO (f)->width; 2626 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); 2627 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff; 2628 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); 2629 *left_pos = 0; 2630 } 2631 2632 *width = newwidth; 2633 *height = newheight; 2634} 2635 2636 2637/* Change the parameters of frame F as specified by ALIST. 2638 If a parameter is not specially recognized, do nothing special; 2639 otherwise call the `x_set_...' function for that parameter. 2640 Except for certain geometry properties, always call store_frame_param 2641 to store the new value in the parameter alist. */ 2642 2643void 2644x_set_frame_parameters (f, alist) 2645 FRAME_PTR f; 2646 Lisp_Object alist; 2647{ 2648 Lisp_Object tail; 2649 2650 /* If both of these parameters are present, it's more efficient to 2651 set them both at once. So we wait until we've looked at the 2652 entire list before we set them. */ 2653 int width, height; 2654 2655 /* Same here. */ 2656 Lisp_Object left, top; 2657 2658 /* Same with these. */ 2659 Lisp_Object icon_left, icon_top; 2660 2661 /* Record in these vectors all the parms specified. */ 2662 Lisp_Object *parms; 2663 Lisp_Object *values; 2664 int i, p; 2665 int left_no_change = 0, top_no_change = 0; 2666 int icon_left_no_change = 0, icon_top_no_change = 0; 2667 int fullscreen_is_being_set = 0; 2668 2669 struct gcpro gcpro1, gcpro2; 2670 2671 i = 0; 2672 for (tail = alist; CONSP (tail); tail = Fcdr (tail)) 2673 i++; 2674 2675 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); 2676 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); 2677 2678 /* Extract parm names and values into those vectors. */ 2679 2680 i = 0; 2681 for (tail = alist; CONSP (tail); tail = Fcdr (tail)) 2682 { 2683 Lisp_Object elt; 2684 2685 elt = Fcar (tail); 2686 parms[i] = Fcar (elt); 2687 values[i] = Fcdr (elt); 2688 i++; 2689 } 2690 /* TAIL and ALIST are not used again below here. */ 2691 alist = tail = Qnil; 2692 2693 GCPRO2 (*parms, *values); 2694 gcpro1.nvars = i; 2695 gcpro2.nvars = i; 2696 2697 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, 2698 because their values appear in VALUES and strings are not valid. */ 2699 top = left = Qunbound; 2700 icon_left = icon_top = Qunbound; 2701 2702 /* Provide default values for HEIGHT and WIDTH. */ 2703 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); 2704 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); 2705 2706 /* Process foreground_color and background_color before anything else. 2707 They are independent of other properties, but other properties (e.g., 2708 cursor_color) are dependent upon them. */ 2709 /* Process default font as well, since fringe widths depends on it. */ 2710 /* Also, process fullscreen, width and height depend upon that */ 2711 for (p = 0; p < i; p++) 2712 { 2713 Lisp_Object prop, val; 2714 2715 prop = parms[p]; 2716 val = values[p]; 2717 if (EQ (prop, Qforeground_color) 2718 || EQ (prop, Qbackground_color) 2719 || EQ (prop, Qfont) 2720 || EQ (prop, Qfullscreen)) 2721 { 2722 register Lisp_Object param_index, old_value; 2723 int count = SPECPDL_INDEX (); 2724 2725 old_value = get_frame_param (f, prop); 2726 fullscreen_is_being_set |= EQ (prop, Qfullscreen); 2727 2728 if (NILP (Fequal (val, old_value))) 2729 { 2730 /* For :font attributes, the frame_parm_handler 2731 x_set_font calls `face-set-after-frame-default'. 2732 Unless we bind inhibit-face-set-after-frame-default 2733 here, this would reset the :font attribute that we 2734 just applied to the default value for new faces. */ 2735 specbind (Qinhibit_face_set_after_frame_default, Qt); 2736 2737 store_frame_param (f, prop, val); 2738 2739 param_index = Fget (prop, Qx_frame_parameter); 2740 if (NATNUMP (param_index) 2741 && (XFASTINT (param_index) 2742 < sizeof (frame_parms)/sizeof (frame_parms[0])) 2743 && rif->frame_parm_handlers[XINT (param_index)]) 2744 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); 2745 2746 unbind_to (count, Qnil); 2747 } 2748 } 2749 } 2750 2751 /* Now process them in reverse of specified order. */ 2752 for (i--; i >= 0; i--) 2753 { 2754 Lisp_Object prop, val; 2755 2756 prop = parms[i]; 2757 val = values[i]; 2758 2759 if (EQ (prop, Qwidth) && NUMBERP (val)) 2760 width = XFASTINT (val); 2761 else if (EQ (prop, Qheight) && NUMBERP (val)) 2762 height = XFASTINT (val); 2763 else if (EQ (prop, Qtop)) 2764 top = val; 2765 else if (EQ (prop, Qleft)) 2766 left = val; 2767 else if (EQ (prop, Qicon_top)) 2768 icon_top = val; 2769 else if (EQ (prop, Qicon_left)) 2770 icon_left = val; 2771 else if (EQ (prop, Qforeground_color) 2772 || EQ (prop, Qbackground_color) 2773 || EQ (prop, Qfont) 2774 || EQ (prop, Qfullscreen)) 2775 /* Processed above. */ 2776 continue; 2777 else 2778 { 2779 register Lisp_Object param_index, old_value; 2780 2781 old_value = get_frame_param (f, prop); 2782 2783 store_frame_param (f, prop, val); 2784 2785 param_index = Fget (prop, Qx_frame_parameter); 2786 if (NATNUMP (param_index) 2787 && (XFASTINT (param_index) 2788 < sizeof (frame_parms)/sizeof (frame_parms[0])) 2789 && rif->frame_parm_handlers[XINT (param_index)]) 2790 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); 2791 } 2792 } 2793 2794 /* Don't die if just one of these was set. */ 2795 if (EQ (left, Qunbound)) 2796 { 2797 left_no_change = 1; 2798 if (f->left_pos < 0) 2799 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil)); 2800 else 2801 XSETINT (left, f->left_pos); 2802 } 2803 if (EQ (top, Qunbound)) 2804 { 2805 top_no_change = 1; 2806 if (f->top_pos < 0) 2807 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil)); 2808 else 2809 XSETINT (top, f->top_pos); 2810 } 2811 2812 /* If one of the icon positions was not set, preserve or default it. */ 2813 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left)) 2814 { 2815 icon_left_no_change = 1; 2816 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist)); 2817 if (NILP (icon_left)) 2818 XSETINT (icon_left, 0); 2819 } 2820 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top)) 2821 { 2822 icon_top_no_change = 1; 2823 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist)); 2824 if (NILP (icon_top)) 2825 XSETINT (icon_top, 0); 2826 } 2827 2828 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) 2829 { 2830 /* If the frame is visible already and the fullscreen parameter is 2831 being set, it is too late to set WM manager hints to specify 2832 size and position. 2833 Here we first get the width, height and position that applies to 2834 fullscreen. We then move the frame to the appropriate 2835 position. Resize of the frame is taken care of in the code after 2836 this if-statement. */ 2837 int new_left, new_top; 2838 2839 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left); 2840 if (new_top != f->top_pos || new_left != f->left_pos) 2841 x_set_offset (f, new_left, new_top, 1); 2842 } 2843 2844 /* Don't set these parameters unless they've been explicitly 2845 specified. The window might be mapped or resized while we're in 2846 this function, and we don't want to override that unless the lisp 2847 code has asked for it. 2848 2849 Don't set these parameters unless they actually differ from the 2850 window's current parameters; the window may not actually exist 2851 yet. */ 2852 { 2853 Lisp_Object frame; 2854 2855 check_frame_size (f, &height, &width); 2856 2857 XSETFRAME (frame, f); 2858 2859 if (width != FRAME_COLS (f) 2860 || height != FRAME_LINES (f) 2861 || f->new_text_lines || f->new_text_cols) 2862 Fset_frame_size (frame, make_number (width), make_number (height)); 2863 2864 if ((!NILP (left) || !NILP (top)) 2865 && ! (left_no_change && top_no_change) 2866 && ! (NUMBERP (left) && XINT (left) == f->left_pos 2867 && NUMBERP (top) && XINT (top) == f->top_pos)) 2868 { 2869 int leftpos = 0; 2870 int toppos = 0; 2871 2872 /* Record the signs. */ 2873 f->size_hint_flags &= ~ (XNegative | YNegative); 2874 if (EQ (left, Qminus)) 2875 f->size_hint_flags |= XNegative; 2876 else if (INTEGERP (left)) 2877 { 2878 leftpos = XINT (left); 2879 if (leftpos < 0) 2880 f->size_hint_flags |= XNegative; 2881 } 2882 else if (CONSP (left) && EQ (XCAR (left), Qminus) 2883 && CONSP (XCDR (left)) 2884 && INTEGERP (XCAR (XCDR (left)))) 2885 { 2886 leftpos = - XINT (XCAR (XCDR (left))); 2887 f->size_hint_flags |= XNegative; 2888 } 2889 else if (CONSP (left) && EQ (XCAR (left), Qplus) 2890 && CONSP (XCDR (left)) 2891 && INTEGERP (XCAR (XCDR (left)))) 2892 { 2893 leftpos = XINT (XCAR (XCDR (left))); 2894 } 2895 2896 if (EQ (top, Qminus)) 2897 f->size_hint_flags |= YNegative; 2898 else if (INTEGERP (top)) 2899 { 2900 toppos = XINT (top); 2901 if (toppos < 0) 2902 f->size_hint_flags |= YNegative; 2903 } 2904 else if (CONSP (top) && EQ (XCAR (top), Qminus) 2905 && CONSP (XCDR (top)) 2906 && INTEGERP (XCAR (XCDR (top)))) 2907 { 2908 toppos = - XINT (XCAR (XCDR (top))); 2909 f->size_hint_flags |= YNegative; 2910 } 2911 else if (CONSP (top) && EQ (XCAR (top), Qplus) 2912 && CONSP (XCDR (top)) 2913 && INTEGERP (XCAR (XCDR (top)))) 2914 { 2915 toppos = XINT (XCAR (XCDR (top))); 2916 } 2917 2918 2919 /* Store the numeric value of the position. */ 2920 f->top_pos = toppos; 2921 f->left_pos = leftpos; 2922 2923 f->win_gravity = NorthWestGravity; 2924 2925 /* Actually set that position, and convert to absolute. */ 2926 x_set_offset (f, leftpos, toppos, -1); 2927 } 2928 2929 if ((!NILP (icon_left) || !NILP (icon_top)) 2930 && ! (icon_left_no_change && icon_top_no_change)) 2931 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); 2932 } 2933 2934 UNGCPRO; 2935} 2936 2937 2938/* Insert a description of internally-recorded parameters of frame X 2939 into the parameter alist *ALISTPTR that is to be given to the user. 2940 Only parameters that are specific to the X window system 2941 and whose values are not correctly recorded in the frame's 2942 param_alist need to be considered here. */ 2943 2944void 2945x_report_frame_params (f, alistptr) 2946 struct frame *f; 2947 Lisp_Object *alistptr; 2948{ 2949 char buf[16]; 2950 Lisp_Object tem; 2951 2952 /* Represent negative positions (off the top or left screen edge) 2953 in a way that Fmodify_frame_parameters will understand correctly. */ 2954 XSETINT (tem, f->left_pos); 2955 if (f->left_pos >= 0) 2956 store_in_alist (alistptr, Qleft, tem); 2957 else 2958 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); 2959 2960 XSETINT (tem, f->top_pos); 2961 if (f->top_pos >= 0) 2962 store_in_alist (alistptr, Qtop, tem); 2963 else 2964 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); 2965 2966 store_in_alist (alistptr, Qborder_width, 2967 make_number (f->border_width)); 2968 store_in_alist (alistptr, Qinternal_border_width, 2969 make_number (FRAME_INTERNAL_BORDER_WIDTH (f))); 2970 store_in_alist (alistptr, Qleft_fringe, 2971 make_number (FRAME_LEFT_FRINGE_WIDTH (f))); 2972 store_in_alist (alistptr, Qright_fringe, 2973 make_number (FRAME_RIGHT_FRINGE_WIDTH (f))); 2974 store_in_alist (alistptr, Qscroll_bar_width, 2975 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f) 2976 ? make_number (0) 2977 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 2978 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) 2979 /* nil means "use default width" 2980 for non-toolkit scroll bar. 2981 ruler-mode.el depends on this. */ 2982 : Qnil)); 2983 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); 2984 store_in_alist (alistptr, Qwindow_id, 2985 build_string (buf)); 2986#ifdef HAVE_X_WINDOWS 2987#ifdef USE_X_TOOLKIT 2988 /* Tooltip frame may not have this widget. */ 2989 if (FRAME_X_OUTPUT (f)->widget) 2990#endif 2991 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f)); 2992 store_in_alist (alistptr, Qouter_window_id, 2993 build_string (buf)); 2994#endif 2995 store_in_alist (alistptr, Qicon_name, f->icon_name); 2996 FRAME_SAMPLE_VISIBILITY (f); 2997 store_in_alist (alistptr, Qvisibility, 2998 (FRAME_VISIBLE_P (f) ? Qt 2999 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); 3000 store_in_alist (alistptr, Qdisplay, 3001 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); 3002 3003 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) 3004 tem = Qnil; 3005 else 3006 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); 3007 store_in_alist (alistptr, Qparent_id, tem); 3008} 3009 3010 3011/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is 3012 the previous value of that parameter, NEW_VALUE is the new value. */ 3013 3014void 3015x_set_fullscreen (f, new_value, old_value) 3016 struct frame *f; 3017 Lisp_Object new_value, old_value; 3018{ 3019 if (NILP (new_value)) 3020 f->want_fullscreen = FULLSCREEN_NONE; 3021 else if (EQ (new_value, Qfullboth)) 3022 f->want_fullscreen = FULLSCREEN_BOTH; 3023 else if (EQ (new_value, Qfullwidth)) 3024 f->want_fullscreen = FULLSCREEN_WIDTH; 3025 else if (EQ (new_value, Qfullheight)) 3026 f->want_fullscreen = FULLSCREEN_HEIGHT; 3027 3028 if (fullscreen_hook != NULL) 3029 fullscreen_hook (f); 3030} 3031 3032 3033/* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is 3034 the previous value of that parameter, NEW_VALUE is the new value. */ 3035 3036void 3037x_set_line_spacing (f, new_value, old_value) 3038 struct frame *f; 3039 Lisp_Object new_value, old_value; 3040{ 3041 if (NILP (new_value)) 3042 f->extra_line_spacing = 0; 3043 else if (NATNUMP (new_value)) 3044 f->extra_line_spacing = XFASTINT (new_value); 3045 else 3046 signal_error ("Invalid line-spacing", new_value); 3047 if (FRAME_VISIBLE_P (f)) 3048 redraw_frame (f); 3049} 3050 3051 3052/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is 3053 the previous value of that parameter, NEW_VALUE is the new value. */ 3054 3055void 3056x_set_screen_gamma (f, new_value, old_value) 3057 struct frame *f; 3058 Lisp_Object new_value, old_value; 3059{ 3060 Lisp_Object bgcolor; 3061 3062 if (NILP (new_value)) 3063 f->gamma = 0; 3064 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0) 3065 /* The value 0.4545 is the normal viewing gamma. */ 3066 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value)); 3067 else 3068 signal_error ("Invalid screen-gamma", new_value); 3069 3070 /* Apply the new gamma value to the frame background. */ 3071 bgcolor = Fassq (Qbackground_color, f->param_alist); 3072 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor))) 3073 { 3074 Lisp_Object index = Fget (Qbackground_color, Qx_frame_parameter); 3075 if (NATNUMP (index) 3076 && (XFASTINT (index) 3077 < sizeof (frame_parms)/sizeof (frame_parms[0])) 3078 && rif->frame_parm_handlers[XFASTINT (index)]) 3079 (*(rif->frame_parm_handlers[XFASTINT (index)])) 3080 (f, bgcolor, Qnil); 3081 } 3082 3083 Fclear_face_cache (Qnil); 3084} 3085 3086 3087void 3088x_set_font (f, arg, oldval) 3089 struct frame *f; 3090 Lisp_Object arg, oldval; 3091{ 3092 Lisp_Object result; 3093 Lisp_Object fontset_name; 3094 Lisp_Object frame; 3095 int old_fontset = FRAME_FONTSET(f); 3096 3097 CHECK_STRING (arg); 3098 3099 fontset_name = Fquery_fontset (arg, Qnil); 3100 3101 BLOCK_INPUT; 3102 result = (STRINGP (fontset_name) 3103 ? x_new_fontset (f, SDATA (fontset_name)) 3104 : x_new_font (f, SDATA (arg))); 3105 UNBLOCK_INPUT; 3106 3107 if (EQ (result, Qnil)) 3108 error ("Font `%s' is not defined", SDATA (arg)); 3109 else if (EQ (result, Qt)) 3110 error ("The characters of the given font have varying widths"); 3111 else if (STRINGP (result)) 3112 { 3113 set_default_ascii_font (result); 3114 if (STRINGP (fontset_name)) 3115 { 3116 /* Fontset names are built from ASCII font names, so the 3117 names may be equal despite there was a change. */ 3118 if (old_fontset == FRAME_FONTSET (f)) 3119 return; 3120 } 3121 else if (!NILP (Fequal (result, oldval))) 3122 return; 3123 3124 /* Recalculate toolbar height. */ 3125 f->n_tool_bar_rows = 0; 3126 /* Ensure we redraw it. */ 3127 clear_current_matrices (f); 3128 3129 store_frame_param (f, Qfont, result); 3130 recompute_basic_faces (f); 3131 } 3132 else 3133 abort (); 3134 3135 do_pending_window_change (0); 3136 3137 /* Don't call `face-set-after-frame-default' when faces haven't been 3138 initialized yet. This is the case when called from 3139 Fx_create_frame. In that case, the X widget or window doesn't 3140 exist either, and we can end up in x_report_frame_params with a 3141 null widget which gives a segfault. */ 3142 if (FRAME_FACE_CACHE (f)) 3143 { 3144 XSETFRAME (frame, f); 3145 call1 (Qface_set_after_frame_default, frame); 3146 } 3147} 3148 3149 3150void 3151x_set_fringe_width (f, new_value, old_value) 3152 struct frame *f; 3153 Lisp_Object new_value, old_value; 3154{ 3155 compute_fringe_widths (f, 1); 3156} 3157 3158void 3159x_set_border_width (f, arg, oldval) 3160 struct frame *f; 3161 Lisp_Object arg, oldval; 3162{ 3163 CHECK_NUMBER (arg); 3164 3165 if (XINT (arg) == f->border_width) 3166 return; 3167 3168 if (FRAME_X_WINDOW (f) != 0) 3169 error ("Cannot change the border width of a frame"); 3170 3171 f->border_width = XINT (arg); 3172} 3173 3174void 3175x_set_internal_border_width (f, arg, oldval) 3176 struct frame *f; 3177 Lisp_Object arg, oldval; 3178{ 3179 int old = FRAME_INTERNAL_BORDER_WIDTH (f); 3180 3181 CHECK_NUMBER (arg); 3182 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg); 3183 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0) 3184 FRAME_INTERNAL_BORDER_WIDTH (f) = 0; 3185 3186#ifdef USE_X_TOOLKIT 3187 if (FRAME_X_OUTPUT (f)->edit_widget) 3188 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget); 3189#endif 3190 3191 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old) 3192 return; 3193 3194 if (FRAME_X_WINDOW (f) != 0) 3195 { 3196 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3197 SET_FRAME_GARBAGED (f); 3198 do_pending_window_change (0); 3199 } 3200 else 3201 SET_FRAME_GARBAGED (f); 3202} 3203 3204void 3205x_set_visibility (f, value, oldval) 3206 struct frame *f; 3207 Lisp_Object value, oldval; 3208{ 3209 Lisp_Object frame; 3210 XSETFRAME (frame, f); 3211 3212 if (NILP (value)) 3213 Fmake_frame_invisible (frame, Qt); 3214 else if (EQ (value, Qicon)) 3215 Ficonify_frame (frame); 3216 else 3217 Fmake_frame_visible (frame); 3218} 3219 3220void 3221x_set_autoraise (f, arg, oldval) 3222 struct frame *f; 3223 Lisp_Object arg, oldval; 3224{ 3225 f->auto_raise = !EQ (Qnil, arg); 3226} 3227 3228void 3229x_set_autolower (f, arg, oldval) 3230 struct frame *f; 3231 Lisp_Object arg, oldval; 3232{ 3233 f->auto_lower = !EQ (Qnil, arg); 3234} 3235 3236void 3237x_set_unsplittable (f, arg, oldval) 3238 struct frame *f; 3239 Lisp_Object arg, oldval; 3240{ 3241 f->no_split = !NILP (arg); 3242} 3243 3244void 3245x_set_vertical_scroll_bars (f, arg, oldval) 3246 struct frame *f; 3247 Lisp_Object arg, oldval; 3248{ 3249 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) 3250 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) 3251 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f)) 3252 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))) 3253 { 3254 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) 3255 = (NILP (arg) 3256 ? vertical_scroll_bar_none 3257 : EQ (Qleft, arg) 3258 ? vertical_scroll_bar_left 3259 : EQ (Qright, arg) 3260 ? vertical_scroll_bar_right 3261 : EQ (Qleft, Vdefault_frame_scroll_bars) 3262 ? vertical_scroll_bar_left 3263 : EQ (Qright, Vdefault_frame_scroll_bars) 3264 ? vertical_scroll_bar_right 3265 : vertical_scroll_bar_none); 3266 3267 /* We set this parameter before creating the X window for the 3268 frame, so we can get the geometry right from the start. 3269 However, if the window hasn't been created yet, we shouldn't 3270 call x_set_window_size. */ 3271 if (FRAME_X_WINDOW (f)) 3272 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3273 do_pending_window_change (0); 3274 } 3275} 3276 3277void 3278x_set_scroll_bar_width (f, arg, oldval) 3279 struct frame *f; 3280 Lisp_Object arg, oldval; 3281{ 3282 int wid = FRAME_COLUMN_WIDTH (f); 3283 3284 if (NILP (arg)) 3285 { 3286 x_set_scroll_bar_default_width (f); 3287 3288 if (FRAME_X_WINDOW (f)) 3289 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3290 do_pending_window_change (0); 3291 } 3292 else if (INTEGERP (arg) && XINT (arg) > 0 3293 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) 3294 { 3295 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) 3296 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1); 3297 3298 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); 3299 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; 3300 if (FRAME_X_WINDOW (f)) 3301 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3302 do_pending_window_change (0); 3303 } 3304 3305 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0); 3306 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; 3307 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; 3308} 3309 3310 3311 3312/* Return non-nil if frame F wants a bitmap icon. */ 3313 3314Lisp_Object 3315x_icon_type (f) 3316 FRAME_PTR f; 3317{ 3318 Lisp_Object tem; 3319 3320 tem = assq_no_quit (Qicon_type, f->param_alist); 3321 if (CONSP (tem)) 3322 return XCDR (tem); 3323 else 3324 return Qnil; 3325} 3326 3327 3328/* Subroutines of creating an X frame. */ 3329 3330/* Make sure that Vx_resource_name is set to a reasonable value. 3331 Fix it up, or set it to `emacs' if it is too hopeless. */ 3332 3333void 3334validate_x_resource_name () 3335{ 3336 int len = 0; 3337 /* Number of valid characters in the resource name. */ 3338 int good_count = 0; 3339 /* Number of invalid characters in the resource name. */ 3340 int bad_count = 0; 3341 Lisp_Object new; 3342 int i; 3343 3344 if (!STRINGP (Vx_resource_class)) 3345 Vx_resource_class = build_string (EMACS_CLASS); 3346 3347 if (STRINGP (Vx_resource_name)) 3348 { 3349 unsigned char *p = SDATA (Vx_resource_name); 3350 int i; 3351 3352 len = SBYTES (Vx_resource_name); 3353 3354 /* Only letters, digits, - and _ are valid in resource names. 3355 Count the valid characters and count the invalid ones. */ 3356 for (i = 0; i < len; i++) 3357 { 3358 int c = p[i]; 3359 if (! ((c >= 'a' && c <= 'z') 3360 || (c >= 'A' && c <= 'Z') 3361 || (c >= '0' && c <= '9') 3362 || c == '-' || c == '_')) 3363 bad_count++; 3364 else 3365 good_count++; 3366 } 3367 } 3368 else 3369 /* Not a string => completely invalid. */ 3370 bad_count = 5, good_count = 0; 3371 3372 /* If name is valid already, return. */ 3373 if (bad_count == 0) 3374 return; 3375 3376 /* If name is entirely invalid, or nearly so, use `emacs'. */ 3377 if (good_count == 0 3378 || (good_count == 1 && bad_count > 0)) 3379 { 3380 Vx_resource_name = build_string ("emacs"); 3381 return; 3382 } 3383 3384 /* Name is partly valid. Copy it and replace the invalid characters 3385 with underscores. */ 3386 3387 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name); 3388 3389 for (i = 0; i < len; i++) 3390 { 3391 int c = SREF (new, i); 3392 if (! ((c >= 'a' && c <= 'z') 3393 || (c >= 'A' && c <= 'Z') 3394 || (c >= '0' && c <= '9') 3395 || c == '-' || c == '_')) 3396 SSET (new, i, '_'); 3397 } 3398} 3399 3400 3401extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *)); 3402extern Display_Info *check_x_display_info P_ ((Lisp_Object)); 3403 3404 3405/* Get specified attribute from resource database RDB. 3406 See Fx_get_resource below for other parameters. */ 3407 3408static Lisp_Object 3409xrdb_get_resource (rdb, attribute, class, component, subclass) 3410 XrmDatabase rdb; 3411 Lisp_Object attribute, class, component, subclass; 3412{ 3413 register char *value; 3414 char *name_key; 3415 char *class_key; 3416 3417 CHECK_STRING (attribute); 3418 CHECK_STRING (class); 3419 3420 if (!NILP (component)) 3421 CHECK_STRING (component); 3422 if (!NILP (subclass)) 3423 CHECK_STRING (subclass); 3424 if (NILP (component) != NILP (subclass)) 3425 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither"); 3426 3427 validate_x_resource_name (); 3428 3429 /* Allocate space for the components, the dots which separate them, 3430 and the final '\0'. Make them big enough for the worst case. */ 3431 name_key = (char *) alloca (SBYTES (Vx_resource_name) 3432 + (STRINGP (component) 3433 ? SBYTES (component) : 0) 3434 + SBYTES (attribute) 3435 + 3); 3436 3437 class_key = (char *) alloca (SBYTES (Vx_resource_class) 3438 + SBYTES (class) 3439 + (STRINGP (subclass) 3440 ? SBYTES (subclass) : 0) 3441 + 3); 3442 3443 /* Start with emacs.FRAMENAME for the name (the specific one) 3444 and with `Emacs' for the class key (the general one). */ 3445 strcpy (name_key, SDATA (Vx_resource_name)); 3446 strcpy (class_key, SDATA (Vx_resource_class)); 3447 3448 strcat (class_key, "."); 3449 strcat (class_key, SDATA (class)); 3450 3451 if (!NILP (component)) 3452 { 3453 strcat (class_key, "."); 3454 strcat (class_key, SDATA (subclass)); 3455 3456 strcat (name_key, "."); 3457 strcat (name_key, SDATA (component)); 3458 } 3459 3460 strcat (name_key, "."); 3461 strcat (name_key, SDATA (attribute)); 3462 3463 value = x_get_string_resource (rdb, name_key, class_key); 3464 3465 if (value != (char *) 0) 3466 return build_string (value); 3467 else 3468 return Qnil; 3469} 3470 3471 3472DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0, 3473 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database. 3474This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the 3475class, where INSTANCE is the name under which Emacs was invoked, or 3476the name specified by the `-name' or `-rn' command-line arguments. 3477 3478The optional arguments COMPONENT and SUBCLASS add to the key and the 3479class, respectively. You must specify both of them or neither. 3480If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE' 3481and the class is `Emacs.CLASS.SUBCLASS'. */) 3482 (attribute, class, component, subclass) 3483 Lisp_Object attribute, class, component, subclass; 3484{ 3485#ifdef HAVE_X_WINDOWS 3486 check_x (); 3487#endif 3488 3489 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb, 3490 attribute, class, component, subclass); 3491} 3492 3493/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */ 3494 3495Lisp_Object 3496display_x_get_resource (dpyinfo, attribute, class, component, subclass) 3497 Display_Info *dpyinfo; 3498 Lisp_Object attribute, class, component, subclass; 3499{ 3500 return xrdb_get_resource (dpyinfo->xrdb, 3501 attribute, class, component, subclass); 3502} 3503 3504/* Used when C code wants a resource value. */ 3505 3506char * 3507x_get_resource_string (attribute, class) 3508 char *attribute, *class; 3509{ 3510 char *name_key; 3511 char *class_key; 3512 struct frame *sf = SELECTED_FRAME (); 3513 3514 /* Allocate space for the components, the dots which separate them, 3515 and the final '\0'. */ 3516 name_key = (char *) alloca (SBYTES (Vinvocation_name) 3517 + strlen (attribute) + 2); 3518 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) 3519 + strlen (class) + 2); 3520 3521 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute); 3522 sprintf (class_key, "%s.%s", EMACS_CLASS, class); 3523 3524 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, 3525 name_key, class_key); 3526} 3527 3528 3529/* Return the value of parameter PARAM. 3530 3531 First search ALIST, then Vdefault_frame_alist, then the X defaults 3532 database, using ATTRIBUTE as the attribute name and CLASS as its class. 3533 3534 Convert the resource to the type specified by desired_type. 3535 3536 If no default is specified, return Qunbound. If you call 3537 x_get_arg, make sure you deal with Qunbound in a reasonable way, 3538 and don't let it get stored in any Lisp-visible variables! */ 3539 3540Lisp_Object 3541x_get_arg (dpyinfo, alist, param, attribute, class, type) 3542 Display_Info *dpyinfo; 3543 Lisp_Object alist, param; 3544 char *attribute; 3545 char *class; 3546 enum resource_types type; 3547{ 3548 register Lisp_Object tem; 3549 3550 tem = Fassq (param, alist); 3551 3552 if (!NILP (tem)) 3553 { 3554 /* If we find this parm in ALIST, clear it out 3555 so that it won't be "left over" at the end. */ 3556#ifndef WINDOWSNT /* w32fns.c has not yet been changed to cope with this. */ 3557 Lisp_Object tail; 3558 XSETCAR (tem, Qnil); 3559 /* In case the parameter appears more than once in the alist, 3560 clear it out. */ 3561 for (tail = alist; CONSP (tail); tail = XCDR (tail)) 3562 if (CONSP (XCAR (tail)) 3563 && EQ (XCAR (XCAR (tail)), param)) 3564 XSETCAR (XCAR (tail), Qnil); 3565#endif 3566 } 3567 else 3568 tem = Fassq (param, Vdefault_frame_alist); 3569 3570 /* If it wasn't specified in ALIST or the Lisp-level defaults, 3571 look in the X resources. */ 3572 if (EQ (tem, Qnil)) 3573 { 3574 if (attribute) 3575 { 3576 tem = display_x_get_resource (dpyinfo, 3577 build_string (attribute), 3578 build_string (class), 3579 Qnil, Qnil); 3580 3581 if (NILP (tem)) 3582 return Qunbound; 3583 3584 switch (type) 3585 { 3586 case RES_TYPE_NUMBER: 3587 return make_number (atoi (SDATA (tem))); 3588 3589 case RES_TYPE_FLOAT: 3590 return make_float (atof (SDATA (tem))); 3591 3592 case RES_TYPE_BOOLEAN: 3593 tem = Fdowncase (tem); 3594 if (!strcmp (SDATA (tem), "on") 3595 || !strcmp (SDATA (tem), "true")) 3596 return Qt; 3597 else 3598 return Qnil; 3599 3600 case RES_TYPE_STRING: 3601 return tem; 3602 3603 case RES_TYPE_SYMBOL: 3604 /* As a special case, we map the values `true' and `on' 3605 to Qt, and `false' and `off' to Qnil. */ 3606 { 3607 Lisp_Object lower; 3608 lower = Fdowncase (tem); 3609 if (!strcmp (SDATA (lower), "on") 3610 || !strcmp (SDATA (lower), "true")) 3611 return Qt; 3612 else if (!strcmp (SDATA (lower), "off") 3613 || !strcmp (SDATA (lower), "false")) 3614 return Qnil; 3615 else 3616 return Fintern (tem, Qnil); 3617 } 3618 3619 default: 3620 abort (); 3621 } 3622 } 3623 else 3624 return Qunbound; 3625 } 3626 return Fcdr (tem); 3627} 3628 3629Lisp_Object 3630x_frame_get_arg (f, alist, param, attribute, class, type) 3631 struct frame *f; 3632 Lisp_Object alist, param; 3633 char *attribute; 3634 char *class; 3635 enum resource_types type; 3636{ 3637 return x_get_arg (FRAME_X_DISPLAY_INFO (f), 3638 alist, param, attribute, class, type); 3639} 3640 3641/* Like x_frame_get_arg, but also record the value in f->param_alist. */ 3642 3643Lisp_Object 3644x_frame_get_and_record_arg (f, alist, param, attribute, class, type) 3645 struct frame *f; 3646 Lisp_Object alist, param; 3647 char *attribute; 3648 char *class; 3649 enum resource_types type; 3650{ 3651 Lisp_Object value; 3652 3653 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param, 3654 attribute, class, type); 3655 if (! NILP (value) && ! EQ (value, Qunbound)) 3656 store_frame_param (f, param, value); 3657 3658 return value; 3659} 3660 3661 3662/* Record in frame F the specified or default value according to ALIST 3663 of the parameter named PROP (a Lisp symbol). 3664 If no value is specified for PROP, look for an X default for XPROP 3665 on the frame named NAME. 3666 If that is not found either, use the value DEFLT. */ 3667 3668Lisp_Object 3669x_default_parameter (f, alist, prop, deflt, xprop, xclass, type) 3670 struct frame *f; 3671 Lisp_Object alist; 3672 Lisp_Object prop; 3673 Lisp_Object deflt; 3674 char *xprop; 3675 char *xclass; 3676 enum resource_types type; 3677{ 3678 Lisp_Object tem; 3679 3680 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type); 3681 if (EQ (tem, Qunbound)) 3682 tem = deflt; 3683 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); 3684 return tem; 3685} 3686 3687 3688 3689 3690DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0, 3691 doc: /* Parse an X-style geometry string STRING. 3692Returns an alist of the form ((top . TOP), (left . LEFT) ... ). 3693The properties returned may include `top', `left', `height', and `width'. 3694The value of `left' or `top' may be an integer, 3695or a list (+ N) meaning N pixels relative to top/left corner, 3696or a list (- N) meaning -N pixels relative to bottom/right corner. */) 3697 (string) 3698 Lisp_Object string; 3699{ 3700 int geometry, x, y; 3701 unsigned int width, height; 3702 Lisp_Object result; 3703 3704 CHECK_STRING (string); 3705 3706 geometry = XParseGeometry ((char *) SDATA (string), 3707 &x, &y, &width, &height); 3708 3709#if 0 3710 if (!!(geometry & XValue) != !!(geometry & YValue)) 3711 error ("Must specify both x and y position, or neither"); 3712#endif 3713 3714 result = Qnil; 3715 if (geometry & XValue) 3716 { 3717 Lisp_Object element; 3718 3719 if (x >= 0 && (geometry & XNegative)) 3720 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil))); 3721 else if (x < 0 && ! (geometry & XNegative)) 3722 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil))); 3723 else 3724 element = Fcons (Qleft, make_number (x)); 3725 result = Fcons (element, result); 3726 } 3727 3728 if (geometry & YValue) 3729 { 3730 Lisp_Object element; 3731 3732 if (y >= 0 && (geometry & YNegative)) 3733 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil))); 3734 else if (y < 0 && ! (geometry & YNegative)) 3735 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil))); 3736 else 3737 element = Fcons (Qtop, make_number (y)); 3738 result = Fcons (element, result); 3739 } 3740 3741 if (geometry & WidthValue) 3742 result = Fcons (Fcons (Qwidth, make_number (width)), result); 3743 if (geometry & HeightValue) 3744 result = Fcons (Fcons (Qheight, make_number (height)), result); 3745 3746 return result; 3747} 3748 3749/* Calculate the desired size and position of frame F. 3750 Return the flags saying which aspects were specified. 3751 3752 Also set the win_gravity and size_hint_flags of F. 3753 3754 Adjust height for toolbar if TOOLBAR_P is 1. 3755 3756 This function does not make the coordinates positive. */ 3757 3758#define DEFAULT_ROWS 40 3759#define DEFAULT_COLS 80 3760 3761int 3762x_figure_window_size (f, parms, toolbar_p) 3763 struct frame *f; 3764 Lisp_Object parms; 3765 int toolbar_p; 3766{ 3767 register Lisp_Object tem0, tem1, tem2; 3768 long window_prompting = 0; 3769 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 3770 3771 /* Default values if we fall through. 3772 Actually, if that happens we should get 3773 window manager prompting. */ 3774 SET_FRAME_COLS (f, DEFAULT_COLS); 3775 FRAME_LINES (f) = DEFAULT_ROWS; 3776 /* Window managers expect that if program-specified 3777 positions are not (0,0), they're intentional, not defaults. */ 3778 f->top_pos = 0; 3779 f->left_pos = 0; 3780 3781 /* Ensure that old new_text_cols and new_text_lines will not override the 3782 values set here. */ 3783 /* ++KFS: This was specific to W32, but seems ok for all platforms */ 3784 f->new_text_cols = f->new_text_lines = 0; 3785 3786 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER); 3787 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER); 3788 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER); 3789 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) 3790 { 3791 if (!EQ (tem0, Qunbound)) 3792 { 3793 CHECK_NUMBER (tem0); 3794 FRAME_LINES (f) = XINT (tem0); 3795 } 3796 if (!EQ (tem1, Qunbound)) 3797 { 3798 CHECK_NUMBER (tem1); 3799 SET_FRAME_COLS (f, XINT (tem1)); 3800 } 3801 if (!NILP (tem2) && !EQ (tem2, Qunbound)) 3802 window_prompting |= USSize; 3803 else 3804 window_prompting |= PSize; 3805 } 3806 3807 f->scroll_bar_actual_width 3808 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); 3809 3810 /* This used to be done _before_ calling x_figure_window_size, but 3811 since the height is reset here, this was really a no-op. I 3812 assume that moving it here does what Gerd intended (although he 3813 no longer can remember what that was... ++KFS, 2003-03-25. */ 3814 3815 /* Add the tool-bar height to the initial frame height so that the 3816 user gets a text display area of the size he specified with -g or 3817 via .Xdefaults. Later changes of the tool-bar height don't 3818 change the frame size. This is done so that users can create 3819 tall Emacs frames without having to guess how tall the tool-bar 3820 will get. */ 3821 if (toolbar_p && FRAME_TOOL_BAR_LINES (f)) 3822 { 3823 int margin, relief, bar_height; 3824 3825 relief = (tool_bar_button_relief >= 0 3826 ? tool_bar_button_relief 3827 : DEFAULT_TOOL_BAR_BUTTON_RELIEF); 3828 3829 if (INTEGERP (Vtool_bar_button_margin) 3830 && XINT (Vtool_bar_button_margin) > 0) 3831 margin = XFASTINT (Vtool_bar_button_margin); 3832 else if (CONSP (Vtool_bar_button_margin) 3833 && INTEGERP (XCDR (Vtool_bar_button_margin)) 3834 && XINT (XCDR (Vtool_bar_button_margin)) > 0) 3835 margin = XFASTINT (XCDR (Vtool_bar_button_margin)); 3836 else 3837 margin = 0; 3838 3839 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; 3840 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 3841 } 3842 3843 compute_fringe_widths (f, 0); 3844 3845 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f)); 3846 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); 3847 3848 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER); 3849 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER); 3850 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER); 3851 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) 3852 { 3853 if (EQ (tem0, Qminus)) 3854 { 3855 f->top_pos = 0; 3856 window_prompting |= YNegative; 3857 } 3858 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) 3859 && CONSP (XCDR (tem0)) 3860 && INTEGERP (XCAR (XCDR (tem0)))) 3861 { 3862 f->top_pos = - XINT (XCAR (XCDR (tem0))); 3863 window_prompting |= YNegative; 3864 } 3865 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) 3866 && CONSP (XCDR (tem0)) 3867 && INTEGERP (XCAR (XCDR (tem0)))) 3868 { 3869 f->top_pos = XINT (XCAR (XCDR (tem0))); 3870 } 3871 else if (EQ (tem0, Qunbound)) 3872 f->top_pos = 0; 3873 else 3874 { 3875 CHECK_NUMBER (tem0); 3876 f->top_pos = XINT (tem0); 3877 if (f->top_pos < 0) 3878 window_prompting |= YNegative; 3879 } 3880 3881 if (EQ (tem1, Qminus)) 3882 { 3883 f->left_pos = 0; 3884 window_prompting |= XNegative; 3885 } 3886 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) 3887 && CONSP (XCDR (tem1)) 3888 && INTEGERP (XCAR (XCDR (tem1)))) 3889 { 3890 f->left_pos = - XINT (XCAR (XCDR (tem1))); 3891 window_prompting |= XNegative; 3892 } 3893 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) 3894 && CONSP (XCDR (tem1)) 3895 && INTEGERP (XCAR (XCDR (tem1)))) 3896 { 3897 f->left_pos = XINT (XCAR (XCDR (tem1))); 3898 } 3899 else if (EQ (tem1, Qunbound)) 3900 f->left_pos = 0; 3901 else 3902 { 3903 CHECK_NUMBER (tem1); 3904 f->left_pos = XINT (tem1); 3905 if (f->left_pos < 0) 3906 window_prompting |= XNegative; 3907 } 3908 3909 if (!NILP (tem2) && ! EQ (tem2, Qunbound)) 3910 window_prompting |= USPosition; 3911 else 3912 window_prompting |= PPosition; 3913 } 3914 3915 if (f->want_fullscreen != FULLSCREEN_NONE) 3916 { 3917 int left, top; 3918 int width, height; 3919 3920 /* It takes both for some WM:s to place it where we want */ 3921 window_prompting = USPosition | PPosition; 3922 x_fullscreen_adjust (f, &width, &height, &top, &left); 3923 FRAME_COLS (f) = width; 3924 FRAME_LINES (f) = height; 3925 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); 3926 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); 3927 f->left_pos = left; 3928 f->top_pos = top; 3929 } 3930 3931 if (window_prompting & XNegative) 3932 { 3933 if (window_prompting & YNegative) 3934 f->win_gravity = SouthEastGravity; 3935 else 3936 f->win_gravity = NorthEastGravity; 3937 } 3938 else 3939 { 3940 if (window_prompting & YNegative) 3941 f->win_gravity = SouthWestGravity; 3942 else 3943 f->win_gravity = NorthWestGravity; 3944 } 3945 3946 f->size_hint_flags = window_prompting; 3947 3948 return window_prompting; 3949} 3950 3951 3952 3953#endif /* HAVE_WINDOW_SYSTEM */ 3954 3955 3956 3957/*********************************************************************** 3958 Initialization 3959 ***********************************************************************/ 3960 3961void 3962syms_of_frame () 3963{ 3964 Qframep = intern ("framep"); 3965 staticpro (&Qframep); 3966 Qframe_live_p = intern ("frame-live-p"); 3967 staticpro (&Qframe_live_p); 3968 Qheight = intern ("height"); 3969 staticpro (&Qheight); 3970 Qicon = intern ("icon"); 3971 staticpro (&Qicon); 3972 Qminibuffer = intern ("minibuffer"); 3973 staticpro (&Qminibuffer); 3974 Qmodeline = intern ("modeline"); 3975 staticpro (&Qmodeline); 3976 Qonly = intern ("only"); 3977 staticpro (&Qonly); 3978 Qwidth = intern ("width"); 3979 staticpro (&Qwidth); 3980 Qgeometry = intern ("geometry"); 3981 staticpro (&Qgeometry); 3982 Qicon_left = intern ("icon-left"); 3983 staticpro (&Qicon_left); 3984 Qicon_top = intern ("icon-top"); 3985 staticpro (&Qicon_top); 3986 Qleft = intern ("left"); 3987 staticpro (&Qleft); 3988 Qright = intern ("right"); 3989 staticpro (&Qright); 3990 Quser_position = intern ("user-position"); 3991 staticpro (&Quser_position); 3992 Quser_size = intern ("user-size"); 3993 staticpro (&Quser_size); 3994 Qwindow_id = intern ("window-id"); 3995 staticpro (&Qwindow_id); 3996#ifdef HAVE_X_WINDOWS 3997 Qouter_window_id = intern ("outer-window-id"); 3998 staticpro (&Qouter_window_id); 3999#endif 4000 Qparent_id = intern ("parent-id"); 4001 staticpro (&Qparent_id); 4002 Qx = intern ("x"); 4003 staticpro (&Qx); 4004 Qw32 = intern ("w32"); 4005 staticpro (&Qw32); 4006 Qpc = intern ("pc"); 4007 staticpro (&Qpc); 4008 Qmac = intern ("mac"); 4009 staticpro (&Qmac); 4010 Qvisible = intern ("visible"); 4011 staticpro (&Qvisible); 4012 Qbuffer_predicate = intern ("buffer-predicate"); 4013 staticpro (&Qbuffer_predicate); 4014 Qbuffer_list = intern ("buffer-list"); 4015 staticpro (&Qbuffer_list); 4016 Qdisplay_type = intern ("display-type"); 4017 staticpro (&Qdisplay_type); 4018 Qbackground_mode = intern ("background-mode"); 4019 staticpro (&Qbackground_mode); 4020 Qtty_color_mode = intern ("tty-color-mode"); 4021 staticpro (&Qtty_color_mode); 4022 4023 Qface_set_after_frame_default = intern ("face-set-after-frame-default"); 4024 staticpro (&Qface_set_after_frame_default); 4025 4026 Qinhibit_face_set_after_frame_default 4027 = intern ("inhibit-face-set-after-frame-default"); 4028 staticpro (&Qinhibit_face_set_after_frame_default); 4029 4030 Qfullwidth = intern ("fullwidth"); 4031 staticpro (&Qfullwidth); 4032 Qfullheight = intern ("fullheight"); 4033 staticpro (&Qfullheight); 4034 Qfullboth = intern ("fullboth"); 4035 staticpro (&Qfullboth); 4036 Qx_resource_name = intern ("x-resource-name"); 4037 staticpro (&Qx_resource_name); 4038 4039 Qx_frame_parameter = intern ("x-frame-parameter"); 4040 staticpro (&Qx_frame_parameter); 4041 4042 { 4043 int i; 4044 4045 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++) 4046 { 4047 Lisp_Object v = intern (frame_parms[i].name); 4048 if (frame_parms[i].variable) 4049 { 4050 *frame_parms[i].variable = v; 4051 staticpro (frame_parms[i].variable); 4052 } 4053 Fput (v, Qx_frame_parameter, make_number (i)); 4054 } 4055 } 4056 4057#ifdef HAVE_WINDOW_SYSTEM 4058 DEFVAR_LISP ("x-resource-name", &Vx_resource_name, 4059 doc: /* The name Emacs uses to look up X resources. 4060`x-get-resource' uses this as the first component of the instance name 4061when requesting resource values. 4062Emacs initially sets `x-resource-name' to the name under which Emacs 4063was invoked, or to the value specified with the `-name' or `-rn' 4064switches, if present. 4065 4066It may be useful to bind this variable locally around a call 4067to `x-get-resource'. See also the variable `x-resource-class'. */); 4068 Vx_resource_name = Qnil; 4069 4070 DEFVAR_LISP ("x-resource-class", &Vx_resource_class, 4071 doc: /* The class Emacs uses to look up X resources. 4072`x-get-resource' uses this as the first component of the instance class 4073when requesting resource values. 4074 4075Emacs initially sets `x-resource-class' to "Emacs". 4076 4077Setting this variable permanently is not a reasonable thing to do, 4078but binding this variable locally around a call to `x-get-resource' 4079is a reasonable practice. See also the variable `x-resource-name'. */); 4080 Vx_resource_class = build_string (EMACS_CLASS); 4081#endif 4082 4083 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist, 4084 doc: /* Alist of default values for frame creation. 4085These may be set in your init file, like this: 4086 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))) 4087These override values given in window system configuration data, 4088 including X Windows' defaults database. 4089For values specific to the first Emacs frame, see `initial-frame-alist'. 4090For values specific to the separate minibuffer frame, see 4091 `minibuffer-frame-alist'. 4092The `menu-bar-lines' element of the list controls whether new frames 4093 have menu bars; `menu-bar-mode' works by altering this element. 4094Setting this variable does not affect existing frames, only new ones. */); 4095 Vdefault_frame_alist = Qnil; 4096 4097 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars, 4098 doc: /* Default position of scroll bars on this window-system. */); 4099#ifdef HAVE_WINDOW_SYSTEM 4100#if defined(HAVE_NTGUI) || defined(MAC_OS) 4101 /* MS-Windows has scroll bars on the right by default. */ 4102 Vdefault_frame_scroll_bars = Qright; 4103#else 4104 Vdefault_frame_scroll_bars = Qleft; 4105#endif 4106#else 4107 Vdefault_frame_scroll_bars = Qnil; 4108#endif 4109 4110 DEFVAR_LISP ("terminal-frame", &Vterminal_frame, 4111 doc: /* The initial frame-object, which represents Emacs's stdout. */); 4112 4113 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, 4114 doc: /* Non-nil if all of Emacs is iconified and frame updates are not needed. */); 4115 Vemacs_iconified = Qnil; 4116 4117 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function, 4118 doc: /* If non-nil, function to transform normal value of `mouse-position'. 4119`mouse-position' calls this function, passing its usual return value as 4120argument, and returns whatever this function returns. 4121This abnormal hook exists for the benefit of packages like `xt-mouse.el' 4122which need to do mouse handling at the Lisp level. */); 4123 Vmouse_position_function = Qnil; 4124 4125 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight, 4126 doc: /* If non-nil, clickable text is highlighted when mouse is over it. 4127If the value is an integer, highlighting is only shown after moving the 4128mouse, while keyboard input turns off the highlight even when the mouse 4129is over the clickable text. However, the mouse shape still indicates 4130when the mouse is over clickable text. */); 4131 Vmouse_highlight = Qt; 4132 4133 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions, 4134 doc: /* Functions to be run before deleting a frame. 4135The functions are run with one arg, the frame to be deleted. 4136See `delete-frame'. */); 4137 Vdelete_frame_functions = Qnil; 4138 4139 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, 4140 doc: /* Minibufferless frames use this frame's minibuffer. 4141 4142Emacs cannot create minibufferless frames unless this is set to an 4143appropriate surrogate. 4144 4145Emacs consults this variable only when creating minibufferless 4146frames; once the frame is created, it sticks with its assigned 4147minibuffer, no matter what this variable is set to. This means that 4148this variable doesn't necessarily say anything meaningful about the 4149current set of frames, or where the minibuffer is currently being 4150displayed. 4151 4152This variable is local to the current terminal and cannot be buffer-local. */); 4153 4154 staticpro (&Vframe_list); 4155 4156 defsubr (&Sactive_minibuffer_window); 4157 defsubr (&Sframep); 4158 defsubr (&Sframe_live_p); 4159 defsubr (&Smake_terminal_frame); 4160 defsubr (&Shandle_switch_frame); 4161 defsubr (&Sselect_frame); 4162 defsubr (&Sselected_frame); 4163 defsubr (&Swindow_frame); 4164 defsubr (&Sframe_root_window); 4165 defsubr (&Sframe_first_window); 4166 defsubr (&Sframe_selected_window); 4167 defsubr (&Sset_frame_selected_window); 4168 defsubr (&Sframe_list); 4169 defsubr (&Snext_frame); 4170 defsubr (&Sprevious_frame); 4171 defsubr (&Sdelete_frame); 4172 defsubr (&Smouse_position); 4173 defsubr (&Smouse_pixel_position); 4174 defsubr (&Sset_mouse_position); 4175 defsubr (&Sset_mouse_pixel_position); 4176#if 0 4177 defsubr (&Sframe_configuration); 4178 defsubr (&Srestore_frame_configuration); 4179#endif 4180 defsubr (&Smake_frame_visible); 4181 defsubr (&Smake_frame_invisible); 4182 defsubr (&Siconify_frame); 4183 defsubr (&Sframe_visible_p); 4184 defsubr (&Svisible_frame_list); 4185 defsubr (&Sraise_frame); 4186 defsubr (&Slower_frame); 4187 defsubr (&Sredirect_frame_focus); 4188 defsubr (&Sframe_focus); 4189 defsubr (&Sframe_parameters); 4190 defsubr (&Sframe_parameter); 4191 defsubr (&Smodify_frame_parameters); 4192 defsubr (&Sframe_char_height); 4193 defsubr (&Sframe_char_width); 4194 defsubr (&Sframe_pixel_height); 4195 defsubr (&Sframe_pixel_width); 4196 defsubr (&Sset_frame_height); 4197 defsubr (&Sset_frame_width); 4198 defsubr (&Sset_frame_size); 4199 defsubr (&Sset_frame_position); 4200 4201#ifdef HAVE_WINDOW_SYSTEM 4202 defsubr (&Sx_get_resource); 4203 defsubr (&Sx_parse_geometry); 4204#endif 4205 4206} 4207 4208/* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039 4209 (do not change this comment) */ 4210