(linenum→info "unix/slp.c:2238")

emacs/22.1/src/frame.c

    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: 
    5: This file is part of GNU Emacs.
    6: 
    7: GNU Emacs is free software; you can redistribute it and/or modify
    8: it under the terms of the GNU General Public License as published by
    9: the Free Software Foundation; either version 2, or (at your option)
   10: any later version.
   11: 
   12: GNU Emacs is distributed in the hope that it will be useful,
   13: but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: GNU General Public License for more details.
   16: 
   17: You should have received a copy of the GNU General Public License
   18: along with GNU Emacs; see the file COPYING.  If not, write to
   19: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   20: Boston, 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: 
   58: Lisp_Object Vx_resource_name;
   59: 
   60: /* The application class we're using in resource queries.
   61:    Normally "Emacs".  */
   62: 
   63: Lisp_Object Vx_resource_class;
   64: 
   65: #endif
   66: 
   67: Lisp_Object Qframep, Qframe_live_p;
   68: Lisp_Object Qicon, Qmodeline;
   69: Lisp_Object Qonly;
   70: Lisp_Object Qx, Qw32, Qmac, Qpc;
   71: Lisp_Object Qvisible;
   72: Lisp_Object Qdisplay_type;
   73: Lisp_Object Qbackground_mode;
   74: 
   75: Lisp_Object Qx_frame_parameter;
   76: Lisp_Object Qx_resource_name;
   77: 
   78: /* Frame parameters (set or reported).  */
   79: 
   80: Lisp_Object Qauto_raise, Qauto_lower;
   81: Lisp_Object Qborder_color, Qborder_width;
   82: Lisp_Object Qcursor_color, Qcursor_type;
   83: Lisp_Object Qgeometry;  /* Not used */
   84: Lisp_Object Qheight, Qwidth;
   85: Lisp_Object Qleft, Qright;
   86: Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
   87: Lisp_Object Qinternal_border_width;
   88: Lisp_Object Qmouse_color;
   89: Lisp_Object Qminibuffer;
   90: Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
   91: Lisp_Object Qvisibility;
   92: Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
   93: Lisp_Object Qscreen_gamma;
   94: Lisp_Object Qline_spacing;
   95: Lisp_Object Quser_position, Quser_size;
   96: Lisp_Object Qwait_for_wm;
   97: Lisp_Object Qwindow_id;
   98: #ifdef HAVE_X_WINDOWS
   99: Lisp_Object Qouter_window_id;
  100: #endif
  101: Lisp_Object Qparent_id;
  102: Lisp_Object Qtitle, Qname;
  103: Lisp_Object Qunsplittable;
  104: Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
  105: Lisp_Object Qleft_fringe, Qright_fringe;
  106: Lisp_Object Qbuffer_predicate, Qbuffer_list;
  107: Lisp_Object Qtty_color_mode;
  108: 
  109: Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
  110: 
  111: Lisp_Object Qinhibit_face_set_after_frame_default;
  112: Lisp_Object Qface_set_after_frame_default;
  113: 
  114: 
  115: Lisp_Object Vterminal_frame;
  116: Lisp_Object Vdefault_frame_alist;
  117: Lisp_Object Vdefault_frame_scroll_bars;
  118: Lisp_Object Vmouse_position_function;
  119: Lisp_Object Vmouse_highlight;
  120: Lisp_Object Vdelete_frame_functions;
  121: ^L
  122: static void
  123: set_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: 
  150: void
  151: set_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: ^L
  180: Lisp_Object Vemacs_iconified;
  181: Lisp_Object Vframe_list;
  182: 
  183: struct x_output tty_display;
  184: 
  185: extern Lisp_Object Vminibuffer_list;
  186: extern Lisp_Object get_minibuffer ();
  187: extern Lisp_Object Fhandle_switch_frame ();
  188: extern Lisp_Object Fredirect_frame_focus ();
  189: extern Lisp_Object x_get_focus_frame ();
  190: ^L
  191: DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
  192:        doc: /* Return non-nil if OBJECT is a frame.
  193: Value 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.
  198: See 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: 
  221: DEFUN ("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.
  223: Value is nil if OBJECT is not a live frame.  If object is a live
  224: frame, the return value indicates what sort of output device it is
  225: displayed on.  See the documentation of `framep' for possible
  226: return 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: 
  236: struct frame *
  237: make_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: ^L
  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: 
  387: struct frame *
  388: make_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: 
  441: struct frame *
  442: make_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: ^L
  478: /* Construct a frame that refers to the terminal (stdin and stdout).  */
  479: 
  480: static int terminal_frame_count;
  481: 
  482: struct frame *
  483: make_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: 
  561: DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
  562:        1, 1, 0,
  563:        doc: /* Create an additional terminal frame.
  564: You can create multiple frames on a text-only terminal in this way.
  565: Only the selected terminal frame is actually displayed.
  566: This function takes one argument, an alist specifying frame parameters.
  567: In practice, generally you don't need to specify any parameters.
  568: Note 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_siz