aboutsummaryrefslogtreecommitdiffstats
path: root/src/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frame.c')
-rw-r--r--src/frame.c407
1 files changed, 308 insertions, 99 deletions
diff --git a/src/frame.c b/src/frame.c
index 7f4bf274ad9..f14b29c02ef 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -130,6 +130,14 @@ decode_window_system_frame (Lisp_Object frame)
130#endif 130#endif
131} 131}
132 132
133struct frame *
134decode_tty_frame (Lisp_Object frame)
135{
136 struct frame *f = decode_live_frame (frame);
137 check_tty (f);
138 return f;
139}
140
133void 141void
134check_window_system (struct frame *f) 142check_window_system (struct frame *f)
135{ 143{
@@ -141,6 +149,13 @@ check_window_system (struct frame *f)
141 : "Window system is not in use or not initialized"); 149 : "Window system is not in use or not initialized");
142} 150}
143 151
152void
153check_tty (struct frame *f)
154{
155 if (!f || !FRAME_TERMCAP_P (f))
156 error ("tty frame should be used");
157}
158
144/* Return the value of frame parameter PROP in frame FRAME. */ 159/* Return the value of frame parameter PROP in frame FRAME. */
145 160
146Lisp_Object 161Lisp_Object
@@ -182,6 +197,17 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
182 int olines = FRAME_MENU_BAR_LINES (f); 197 int olines = FRAME_MENU_BAR_LINES (f);
183 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0; 198 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
184 199
200 /* FIXME/tty: menu bars on child frames don't work on all platforms,
201 which is the reason why prepare_menu_bar does not update_menu_bar
202 for child frames (info from Martin Rudalics). This could be
203 implemented in ttys, but it's unclear if it is worth it. */
204 if (is_tty_child_frame (f))
205 {
206 FRAME_MENU_BAR_LINES (f) = 0;
207 FRAME_MENU_BAR_HEIGHT (f) = 0;
208 return;
209 }
210
185 /* Right now, menu bars don't work properly in minibuf-only frames; 211 /* Right now, menu bars don't work properly in minibuf-only frames;
186 most of the commands try to apply themselves to the minibuffer 212 most of the commands try to apply themselves to the minibuffer
187 frame itself, and get an error because you can't switch buffers 213 frame itself, and get an error because you can't switch buffers
@@ -389,7 +415,6 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
389} 415}
390 416
391 417
392#ifdef HAVE_WINDOW_SYSTEM
393/** 418/**
394 * keep_ratio: 419 * keep_ratio:
395 * 420 *
@@ -508,7 +533,6 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
508 } 533 }
509 } 534 }
510} 535}
511#endif
512 536
513 537
514static void 538static void
@@ -832,9 +856,11 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
832 resize_frame_windows (f, new_inner_width, true); 856 resize_frame_windows (f, new_inner_width, true);
833 857
834 /* MSDOS frames cannot PRETEND, as they change frame size by 858 /* MSDOS frames cannot PRETEND, as they change frame size by
835 manipulating video hardware. */ 859 manipulating video hardware. FIXME/tty: it looks wrong to set
836 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 860 FrameCols here. See also the comment for FrameRows above. */
837 FrameCols (FRAME_TTY (f)) = new_text_cols; 861 if (is_tty_root_frame (f))
862 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
863 FrameCols (FRAME_TTY (f)) = new_text_cols;
838 864
839#if defined (HAVE_WINDOW_SYSTEM) 865#if defined (HAVE_WINDOW_SYSTEM)
840 if (WINDOWP (f->tab_bar_window)) 866 if (WINDOWP (f->tab_bar_window))
@@ -866,9 +892,15 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
866 resize_frame_windows (f, new_inner_height, false); 892 resize_frame_windows (f, new_inner_height, false);
867 893
868 /* MSDOS frames cannot PRETEND, as they change frame size by 894 /* MSDOS frames cannot PRETEND, as they change frame size by
869 manipulating video hardware. */ 895 manipulating video hardware.
870 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 896
871 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f); 897 FIXME/tty: ti looks strange to set FrameRows here. The terminal
898 emulator window or console has some physical size, and I wonder
899 how one would change that size from here. Or what it is good for
900 to set it here. */
901 if (is_tty_root_frame (f))
902 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
903 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f);
872 } 904 }
873 else if (new_text_lines != old_text_lines) 905 else if (new_text_lines != old_text_lines)
874 call2 (Qwindow__pixel_to_total, frame, Qnil); 906 call2 (Qwindow__pixel_to_total, frame, Qnil);
@@ -910,7 +942,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
910 942
911 unblock_input (); 943 unblock_input ();
912 944
913#ifdef HAVE_WINDOW_SYSTEM
914 { 945 {
915 /* Adjust size of F's child frames. */ 946 /* Adjust size of F's child frames. */
916 Lisp_Object frames, frame1; 947 Lisp_Object frames, frame1;
@@ -920,7 +951,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
920 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height, 951 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height,
921 new_native_width, new_native_height); 952 new_native_width, new_native_height);
922 } 953 }
923#endif
924} 954}
925 955
926/* Allocate basically initialized frame. */ 956/* Allocate basically initialized frame. */
@@ -967,12 +997,12 @@ make_frame (bool mini_p)
967 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 997 f->line_height = 1; /* !FRAME_WINDOW_P value. */
968 f->new_width = -1; 998 f->new_width = -1;
969 f->new_height = -1; 999 f->new_height = -1;
1000 f->no_special_glyphs = false;
970#ifdef HAVE_WINDOW_SYSTEM 1001#ifdef HAVE_WINDOW_SYSTEM
971 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 1002 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
972 f->horizontal_scroll_bars = false; 1003 f->horizontal_scroll_bars = false;
973 f->want_fullscreen = FULLSCREEN_NONE; 1004 f->want_fullscreen = FULLSCREEN_NONE;
974 f->undecorated = false; 1005 f->undecorated = false;
975 f->no_special_glyphs = false;
976#ifndef HAVE_NTGUI 1006#ifndef HAVE_NTGUI
977 f->override_redirect = false; 1007 f->override_redirect = false;
978#endif 1008#endif
@@ -1089,7 +1119,6 @@ make_frame (bool mini_p)
1089 return f; 1119 return f;
1090} 1120}
1091 1121
1092#ifdef HAVE_WINDOW_SYSTEM
1093/* Make a frame using a separate minibuffer window on another frame. 1122/* Make a frame using a separate minibuffer window on another frame.
1094 MINI_WINDOW is the minibuffer window to use. nil means use the 1123 MINI_WINDOW is the minibuffer window to use. nil means use the
1095 default (the global minibuffer). */ 1124 default (the global minibuffer). */
@@ -1183,7 +1212,7 @@ make_minibuffer_frame (void)
1183 : Fcar (Vminibuffer_list)), 0, 0); 1212 : Fcar (Vminibuffer_list)), 0, 0);
1184 return f; 1213 return f;
1185} 1214}
1186#endif /* HAVE_WINDOW_SYSTEM */ 1215
1187 1216
1188/* Construct a frame that refers to a terminal. */ 1217/* Construct a frame that refers to a terminal. */
1189 1218
@@ -1209,7 +1238,7 @@ make_initial_frame (void)
1209 tty_frame_count = 1; 1238 tty_frame_count = 1;
1210 fset_name (f, build_pure_c_string ("F1")); 1239 fset_name (f, build_pure_c_string ("F1"));
1211 1240
1212 SET_FRAME_VISIBLE (f, 1); 1241 SET_FRAME_VISIBLE (f, true);
1213 1242
1214 f->output_method = terminal->type; 1243 f->output_method = terminal->type;
1215 f->terminal = terminal; 1244 f->terminal = terminal;
@@ -1246,23 +1275,56 @@ make_initial_frame (void)
1246#ifndef HAVE_ANDROID 1275#ifndef HAVE_ANDROID
1247 1276
1248static struct frame * 1277static struct frame *
1249make_terminal_frame (struct terminal *terminal) 1278make_terminal_frame (struct terminal *terminal, Lisp_Object parent,
1279 Lisp_Object params)
1250{ 1280{
1251 register struct frame *f;
1252 Lisp_Object frame;
1253 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)]; 1281 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)];
1254 1282
1255 if (!terminal->name) 1283 if (!terminal->name)
1256 error ("Terminal is not live, can't create new frames on it"); 1284 error ("Terminal is not live, can't create new frames on it");
1257 1285
1258 f = make_frame (1); 1286 struct frame *f;
1287 if (NILP (parent))
1288 f = make_frame (true);
1289 else
1290 {
1291 CHECK_FRAME (parent);
1292
1293 f = NULL;
1294 Lisp_Object mini = Fassq (Qminibuffer, params);
1295 if (CONSP (mini))
1296 {
1297 mini = Fcdr (mini);
1298 struct kboard *kb = FRAME_KBOARD (XFRAME (parent));
1299 if (EQ (mini, Qnone) || NILP (mini))
1300 f = make_frame_without_minibuffer (Qnil, kb, Qnil);
1301 else if (EQ (mini, Qonly))
1302 {
1303 /* FIXME/tty: No interest in this feature at the moment,
1304 unless someone complains. */
1305# if 0
1306 f = make_minibuffer_frame ();
1307 /* Not sure about this plus the unsplittable frame
1308 paran. */
1309 f->no_split = true;
1310# endif
1311 }
1312 else if (WINDOWP (mini))
1313 f = make_frame_without_minibuffer (mini, kb, Qnil);
1314 }
1315
1316 if (f == NULL)
1317 f = make_frame (true);
1318 f->parent_frame = parent;
1319 }
1259 1320
1321 Lisp_Object frame;
1260 XSETFRAME (frame, f); 1322 XSETFRAME (frame, f);
1261 Vframe_list = Fcons (frame, Vframe_list); 1323 Vframe_list = Fcons (frame, Vframe_list);
1262 1324
1263 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count)); 1325 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count));
1264 1326
1265 SET_FRAME_VISIBLE (f, 1); 1327 SET_FRAME_VISIBLE (f, true);
1266 1328
1267 f->terminal = terminal; 1329 f->terminal = terminal;
1268 f->terminal->reference_count++; 1330 f->terminal->reference_count++;
@@ -1287,7 +1349,15 @@ make_terminal_frame (struct terminal *terminal)
1287 f->horizontal_scroll_bars = false; 1349 f->horizontal_scroll_bars = false;
1288#endif 1350#endif
1289 1351
1290 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1; 1352 /* FIXME/tty: menu bars on child frames don't work on all platforms,
1353 which is the reason why prepare_menu_bar does not update_menu_bar
1354 for child frames (info from Martin Rudalics). This could be
1355 implemented in ttys, but it's unclear if it is worth it. */
1356 if (NILP (parent))
1357 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
1358 else
1359 FRAME_MENU_BAR_LINES (f) = 0;
1360
1291 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1; 1361 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1;
1292 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f) 1362 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f)
1293 - FRAME_TAB_BAR_LINES (f); 1363 - FRAME_TAB_BAR_LINES (f);
@@ -1296,16 +1366,16 @@ make_terminal_frame (struct terminal *terminal)
1296 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f) 1366 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f)
1297 - FRAME_TAB_BAR_HEIGHT (f); 1367 - FRAME_TAB_BAR_HEIGHT (f);
1298 1368
1299 /* Set the top frame to the newly created frame. */ 1369 /* Mark current topmost frame obscured if we make a new root frame.
1370 Child frames don't completely obscure other frames. */
1300 if (FRAMEP (FRAME_TTY (f)->top_frame) 1371 if (FRAMEP (FRAME_TTY (f)->top_frame)
1301 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) 1372 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))
1302 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */ 1373 && NILP (parent))
1303 1374 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), false);
1304 FRAME_TTY (f)->top_frame = frame;
1305
1306 if (!noninteractive)
1307 init_frame_faces (f);
1308 1375
1376 /* Set the top frame to the newly created frame. */
1377 if (!FRAME_PARENT_FRAME (f))
1378 FRAME_TTY (f)->top_frame = frame;
1309 return f; 1379 return f;
1310} 1380}
1311 1381
@@ -1335,6 +1405,62 @@ get_future_frame_param (Lisp_Object parameter,
1335 1405
1336#endif 1406#endif
1337 1407
1408static int
1409tty_child_pos_param (struct frame *child, Lisp_Object key,
1410 Lisp_Object params, int dflt)
1411{
1412 Lisp_Object val = Fassq (key, params);
1413 if (CONSP (val))
1414 {
1415 val = XCDR (val);
1416 if (FIXNUMP (val))
1417 return XFIXNUM (val);
1418 }
1419 return dflt;
1420}
1421
1422static int
1423tty_child_size_param (struct frame *child, Lisp_Object key,
1424 Lisp_Object params, int dflt)
1425{
1426 Lisp_Object val = Fassq (key, params);
1427 if (CONSP (val))
1428 {
1429 val = XCDR (val);
1430 if (CONSP (val))
1431 {
1432 /* Width and height may look like (width text-pixels
1433 . PIXELS) on window systems. Mimic that. */
1434 val = XCDR (val);
1435 if (EQ (val, Qtext_pixels))
1436 val = XCDR (val);
1437 }
1438 else if (FLOATP (val))
1439 {
1440 /* Width and height may be a float, in which case
1441 it's a multiple of the parent's value. */
1442 struct frame *parent = FRAME_PARENT_FRAME (child);
1443 int sz = (EQ (key, Qwidth) ? FRAME_TOTAL_COLS (parent)
1444 : FRAME_TOTAL_LINES (parent));
1445 val = make_fixnum (XFLOAT_DATA (val) * sz);
1446 }
1447
1448 if (FIXNUMP (val) && XFIXNUM (val) > 0)
1449 return XFIXNUM (val);
1450 }
1451 return dflt;
1452}
1453
1454static void
1455child_frame_rect (struct frame *f, Lisp_Object params,
1456 int *x, int *y, int *w, int *h)
1457{
1458 *x = tty_child_pos_param (f, Qleft, params, 0);
1459 *y = tty_child_pos_param (f, Qtop, params, 0);
1460 *w = tty_child_size_param (f, Qwidth, params, FRAME_TOTAL_COLS (f));
1461 *h = tty_child_size_param (f, Qheight, params, FRAME_TOTAL_LINES (f));
1462}
1463
1338DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, 1464DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
1339 1, 1, 0, 1465 1, 1, 0,
1340 doc: /* Create an additional terminal frame, possibly on another terminal. 1466 doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -1358,9 +1484,7 @@ affects all frames on the same terminal device. */)
1358 error ("Text terminals are not supported on this platform"); 1484 error ("Text terminals are not supported on this platform");
1359 return Qnil; 1485 return Qnil;
1360#else 1486#else
1361 struct frame *f;
1362 struct terminal *t = NULL; 1487 struct terminal *t = NULL;
1363 Lisp_Object frame;
1364 struct frame *sf = SELECTED_FRAME (); 1488 struct frame *sf = SELECTED_FRAME ();
1365 1489
1366#ifdef MSDOS 1490#ifdef MSDOS
@@ -1390,7 +1514,7 @@ affects all frames on the same terminal device. */)
1390 error ("Multiple terminals are not supported on this platform"); 1514 error ("Multiple terminals are not supported on this platform");
1391 if (!t) 1515 if (!t)
1392 t = the_only_display_info.terminal; 1516 t = the_only_display_info.terminal;
1393#endif 1517# endif
1394 } 1518 }
1395 1519
1396 if (!t) 1520 if (!t)
@@ -1417,19 +1541,60 @@ affects all frames on the same terminal device. */)
1417 SAFE_FREE (); 1541 SAFE_FREE ();
1418 } 1542 }
1419 1543
1420 f = make_terminal_frame (t); 1544 /* Make a new frame. We need to know upfront if if a parent frame is
1545 specified because we behave differently in this case, e.g. child
1546 frames don't obscure other frames. */
1547 Lisp_Object parent = Fcdr (Fassq (Qparent_frame, parms));
1548 struct frame *f = make_terminal_frame (t, parent, parms);
1421 1549
1422 { 1550 if (!noninteractive)
1423 int width, height; 1551 init_frame_faces (f);
1424 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1425 /* With INHIBIT 5 pass correct text height to adjust_frame_size. */
1426 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f),
1427 5, 0, Qterminal_frame);
1428 }
1429 1552
1553 /* Visibility of root frames cannot be set with a frame parameter.
1554 Their visibility solely depends on whether or not they are the
1555 top_frame on the terminal. */
1556 if (FRAME_PARENT_FRAME (f))
1557 {
1558 Lisp_Object visible = Fassq (Qvisibility, parms);
1559 if (CONSP (visible))
1560 SET_FRAME_VISIBLE (f, !NILP (visible));
1561
1562 /* FIXME/tty: Not having borders is currently deeply
1563 engraved in the code, so we can't naively do it. */
1564#if 0
1565 Lisp_Object border = Fcdr (Fassq (Qborder_width, parms));
1566 if (FIXNUMP (border))
1567 f->border_width = XFIXNUM (border);
1568 border = Fcdr (Fassq (Qchild_frame_border_width, parms));
1569 if (FIXNUMP (border))
1570 f->child_frame_border_width = XFIXNUM (border);
1571# endif
1572 }
1573
1574 /* Determine width and height of the frame. For root frames use the
1575 width/height of the terminal. For child frames, take it from frame
1576 parameters. Note that a default (80x25) has been set in
1577 make_frame. We handle root frames in this way because otherwise we
1578 would end up needing glyph matrices for the terminal, which is both
1579 more work and has its downsides (think of clipping frames to the
1580 terminal size). */
1581 int x = 0, y = 0, width, height;
1582 if (FRAME_PARENT_FRAME (f))
1583 child_frame_rect (f, parms, &x, &y, &width, &height);
1584 else
1585 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1586 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f), 5, 0,
1587 Qterminal_frame);
1430 adjust_frame_glyphs (f); 1588 adjust_frame_glyphs (f);
1589
1431 calculate_costs (f); 1590 calculate_costs (f);
1432 XSETFRAME (frame, f); 1591
1592 f->left_pos = x;
1593 f->top_pos = y;
1594 store_in_alist (&parms, Qleft, make_fixnum (x));
1595 store_in_alist (&parms, Qtop, make_fixnum (y));
1596 store_in_alist (&parms, Qwidth, make_fixnum (width));
1597 store_in_alist (&parms, Qheight, make_fixnum (height));
1433 1598
1434 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); 1599 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
1435 store_in_alist (&parms, Qtty, 1600 store_in_alist (&parms, Qtty,
@@ -1451,7 +1616,11 @@ affects all frames on the same terminal device. */)
1451 /* On terminal frames the `minibuffer' frame parameter is always 1616 /* On terminal frames the `minibuffer' frame parameter is always
1452 virtually t. Avoid that a different value in parms causes 1617 virtually t. Avoid that a different value in parms causes
1453 complaints, see Bug#24758. */ 1618 complaints, see Bug#24758. */
1454 store_in_alist (&parms, Qminibuffer, Qt); 1619 if (!FRAME_PARENT_FRAME (f))
1620 store_in_alist (&parms, Qminibuffer, Qt);
1621
1622 Lisp_Object frame;
1623 XSETFRAME (frame, f);
1455 Fmodify_frame_parameters (frame, parms); 1624 Fmodify_frame_parameters (frame, parms);
1456 1625
1457 f->can_set_window_size = true; 1626 f->can_set_window_size = true;
@@ -1546,24 +1715,32 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1546 struct tty_display_info *tty = FRAME_TTY (f); 1715 struct tty_display_info *tty = FRAME_TTY (f);
1547 Lisp_Object top_frame = tty->top_frame; 1716 Lisp_Object top_frame = tty->top_frame;
1548 1717
1549 /* Don't mark the frame garbaged and/or obscured if we are 1718 /* Don't mark the frame garbaged if we are switching to the frame
1550 switching to the frame that is already the top frame of that 1719 that is already the top frame of that TTY. */
1551 TTY. */
1552 if (!EQ (frame, top_frame)) 1720 if (!EQ (frame, top_frame))
1553 { 1721 {
1554 if (FRAMEP (top_frame)) 1722 SET_FRAME_VISIBLE (f, true);
1555 /* Mark previously displayed frame as now obscured. */ 1723 if (is_tty_root_frame (f))
1556 SET_FRAME_VISIBLE (XFRAME (top_frame), 2); 1724 {
1557 SET_FRAME_VISIBLE (f, 1); 1725 /* Mark previously displayed frame as no longer visible. */
1558 /* If the new TTY frame changed dimensions, we need to 1726 if (FRAMEP (top_frame))
1559 resync term.c's idea of the frame size with the new 1727 SET_FRAME_VISIBLE (XFRAME (top_frame), false);
1560 frame's data. */ 1728
1561 if (FRAME_COLS (f) != FrameCols (tty)) 1729 tty->top_frame = frame;
1562 FrameCols (tty) = FRAME_COLS (f); 1730
1563 if (FRAME_TOTAL_LINES (f) != FrameRows (tty)) 1731 /* If the new TTY frame changed dimensions, we need to
1564 FrameRows (tty) = FRAME_TOTAL_LINES (f); 1732 resync term.c's idea of the frame size with the new
1733 frame's data. */
1734 /* FIXME/tty: another place where we set
1735 FrameRows/FrameCols, which is really a physical
1736 property of the terminal, and nothing we set. That
1737 doesn't look right to me. */
1738 if (FRAME_COLS (f) != FrameCols (tty))
1739 FrameCols (tty) = FRAME_COLS (f);
1740 if (FRAME_TOTAL_LINES (f) != FrameRows (tty))
1741 FrameRows (tty) = FRAME_TOTAL_LINES (f);
1742 }
1565 } 1743 }
1566 tty->top_frame = frame;
1567 } 1744 }
1568 1745
1569 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window)); 1746 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
@@ -1605,9 +1782,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1605 (select-window (frame-root-window (make-frame))) doesn't end up 1782 (select-window (frame-root-window (make-frame))) doesn't end up
1606 with your typing being interpreted in the new frame instead of 1783 with your typing being interpreted in the new frame instead of
1607 the one you're actually typing in. */ 1784 the one you're actually typing in. */
1608#ifdef HAVE_WINDOW_SYSTEM
1609 if (!frame_ancestor_p (f, sf)) 1785 if (!frame_ancestor_p (f, sf))
1610#endif
1611 internal_last_event_frame = Qnil; 1786 internal_last_event_frame = Qnil;
1612 1787
1613 return frame; 1788 return frame;
@@ -1725,7 +1900,6 @@ parent window is the window-system's root window) or an embedded window
1725 return Qnil; 1900 return Qnil;
1726} 1901}
1727 1902
1728#ifdef HAVE_WINDOW_SYSTEM
1729bool 1903bool
1730frame_ancestor_p (struct frame *af, struct frame *df) 1904frame_ancestor_p (struct frame *af, struct frame *df)
1731{ 1905{
@@ -1741,7 +1915,6 @@ frame_ancestor_p (struct frame *af, struct frame *df)
1741 1915
1742 return false; 1916 return false;
1743} 1917}
1744#endif
1745 1918
1746DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p, 1919DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p,
1747 2, 2, 0, 1920 2, 2, 0,
@@ -1752,15 +1925,10 @@ ANCESTOR and DESCENDANT must be live frames and default to the selected
1752frame. */) 1925frame. */)
1753 (Lisp_Object ancestor, Lisp_Object descendant) 1926 (Lisp_Object ancestor, Lisp_Object descendant)
1754{ 1927{
1755#ifdef HAVE_WINDOW_SYSTEM
1756 struct frame *af = decode_live_frame (ancestor); 1928 struct frame *af = decode_live_frame (ancestor);
1757 struct frame *df = decode_live_frame (descendant); 1929 struct frame *df = decode_live_frame (descendant);
1758
1759 return frame_ancestor_p (af, df) ? Qt : Qnil; 1930 return frame_ancestor_p (af, df) ? Qt : Qnil;
1760#else 1931}
1761 return Qnil;
1762#endif
1763 }
1764 1932
1765/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the 1933/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1766 same tty (for tty frames) or among frames which uses FRAME's keyboard. 1934 same tty (for tty frames) or among frames which uses FRAME's keyboard.
@@ -2282,7 +2450,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2282 fset_root_window (f, Qnil); 2450 fset_root_window (f, Qnil);
2283 2451
2284 Vframe_list = Fdelq (frame, Vframe_list); 2452 Vframe_list = Fdelq (frame, Vframe_list);
2285 SET_FRAME_VISIBLE (f, 0); 2453 SET_FRAME_VISIBLE (f, false);
2286 2454
2287 /* Allow the vector of menu bar contents to be freed in the next 2455 /* Allow the vector of menu bar contents to be freed in the next
2288 garbage collection. The frame object itself may not be garbage 2456 garbage collection. The frame object itself may not be garbage
@@ -2868,6 +3036,9 @@ If omitted, FRAME defaults to the currently selected frame. */)
2868 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3036 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2869 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true); 3037 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true);
2870 3038
3039 if (is_tty_frame (f))
3040 SET_FRAME_VISIBLE (f, true);
3041
2871 make_frame_visible_1 (f->root_window); 3042 make_frame_visible_1 (f->root_window);
2872 3043
2873 /* Make menu bar update for the Buffers and Frames menus. */ 3044 /* Make menu bar update for the Buffers and Frames menus. */
@@ -2918,6 +3089,12 @@ displayed in the terminal. */)
2918 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3089 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2919 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false); 3090 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
2920 3091
3092 /* FIXME/tty: the Elisp info manual says that this "usually" makes
3093 child frames invisible, too, but without saying when not. Since users
3094 can't rely on this, it's not implemented. */
3095 if (is_tty_frame (f))
3096 SET_FRAME_VISIBLE (f, false);
3097
2921 /* Make menu bar update for the Buffers and Frames menus. */ 3098 /* Make menu bar update for the Buffers and Frames menus. */
2922 windows_or_buffers_changed = 16; 3099 windows_or_buffers_changed = 16;
2923 3100
@@ -3012,12 +3189,7 @@ doesn't support multiple overlapping frames, this function selects FRAME. */)
3012 3189
3013 XSETFRAME (frame, f); 3190 XSETFRAME (frame, f);
3014 3191
3015 if (FRAME_TERMCAP_P (f)) 3192 Fmake_frame_visible (frame);
3016 /* On a text terminal select FRAME. */
3017 Fselect_frame (frame, Qnil);
3018 else
3019 /* Do like the documentation says. */
3020 Fmake_frame_visible (frame);
3021 3193
3022 if (FRAME_TERMINAL (f)->frame_raise_lower_hook) 3194 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
3023 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true); 3195 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true);
@@ -3318,6 +3490,16 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
3318 val = old_val; 3490 val = old_val;
3319 } 3491 }
3320 3492
3493 /* FIXME/tty: re-parenting is currently not implemented when changing
3494 a root frame to a child frame or vice versa. Could be done, but
3495 it's unclear if it's worth it. */
3496 if (is_tty_frame (f))
3497 {
3498 if (EQ (prop, Qparent_frame)
3499 && NILP (f->parent_frame) != NILP (val))
3500 error ("Making a root frame a child or vice versa is not supported");
3501 }
3502
3321 /* The tty color needed to be set before the frame's parameter 3503 /* The tty color needed to be set before the frame's parameter
3322 alist was updated with the new value. This is not true any more, 3504 alist was updated with the new value. This is not true any more,
3323 but we still do this test early on. */ 3505 but we still do this test early on. */
@@ -3441,13 +3623,9 @@ If FRAME is omitted or nil, return information on the currently selected frame.
3441 else 3623 else
3442#endif 3624#endif
3443 { 3625 {
3444 /* This ought to be correct in f->param_alist for an X frame. */ 3626 store_in_alist (&alist, Qmenu_bar_lines, make_fixnum (FRAME_MENU_BAR_LINES (f)));
3445 Lisp_Object lines; 3627 store_in_alist (&alist, Qtab_bar_lines, make_fixnum (FRAME_TAB_BAR_LINES (f)));
3446 3628 store_in_alist (&alist, Qvisibility, FRAME_VISIBLE_P (f) ? Qt : Qnil);
3447 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
3448 store_in_alist (&alist, Qmenu_bar_lines, lines);
3449 XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
3450 store_in_alist (&alist, Qtab_bar_lines, lines);
3451 } 3629 }
3452 3630
3453 return alist; 3631 return alist;
@@ -3525,7 +3703,6 @@ If FRAME is nil, describe the currently selected frame. */)
3525 return value; 3703 return value;
3526} 3704}
3527 3705
3528
3529DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 3706DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
3530 Smodify_frame_parameters, 2, 2, 0, 3707 Smodify_frame_parameters, 2, 2, 0,
3531 doc: /* Modify FRAME according to new values of its parameters in ALIST. 3708 doc: /* Modify FRAME according to new values of its parameters in ALIST.
@@ -3563,6 +3740,7 @@ list, but are otherwise ignored. */)
3563 USE_SAFE_ALLOCA; 3740 USE_SAFE_ALLOCA;
3564 SAFE_ALLOCA_LISP (parms, 2 * length); 3741 SAFE_ALLOCA_LISP (parms, 2 * length);
3565 values = parms + length; 3742 values = parms + length;
3743 Lisp_Object params = alist;
3566 3744
3567 /* Extract parm names and values into those vectors. */ 3745 /* Extract parm names and values into those vectors. */
3568 3746
@@ -3588,6 +3766,25 @@ list, but are otherwise ignored. */)
3588 update_face_from_frame_parameter (f, prop, val); 3766 update_face_from_frame_parameter (f, prop, val);
3589 } 3767 }
3590 3768
3769 if (is_tty_child_frame (f))
3770 {
3771 f->left_pos = tty_child_pos_param (f, Qleft, params, f->left_pos);
3772 f->top_pos = tty_child_pos_param (f, Qtop, params, f->top_pos);
3773
3774 int w = tty_child_size_param (f, Qwidth, params, f->total_cols);
3775 int h = tty_child_size_param (f, Qheight, params, f->total_lines);
3776 if (w != f->total_cols || h != f->total_lines)
3777 change_frame_size (f, w, h, false, false, false);
3778
3779 Lisp_Object visible = Fassq (Qvisibility, params);
3780 if (CONSP (visible))
3781 SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
3782
3783 Lisp_Object no_special = Fassq (Qno_special_glyphs, params);
3784 if (CONSP (no_special))
3785 FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (Fcdr (no_special));
3786 }
3787
3591 SAFE_FREE (); 3788 SAFE_FREE ();
3592 } 3789 }
3593 return Qnil; 3790 return Qnil;
@@ -3935,6 +4132,11 @@ bottom edge of FRAME's display. */)
3935 (void) yval; 4132 (void) yval;
3936#endif 4133#endif
3937 } 4134 }
4135 else if (is_tty_child_frame (f))
4136 {
4137 f->left_pos = xval;
4138 f->top_pos = yval;
4139 }
3938 4140
3939 return Qt; 4141 return Qt;
3940} 4142}
@@ -4246,6 +4448,28 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
4246 } 4448 }
4247} 4449}
4248 4450
4451/* Handle frame parameter change with frame parameter handler. F is the
4452 frame whose frame parameter was changed. PROP is the name of the
4453 frame parameter. VAL and OLD_VALUE are the current value and old
4454 value of the frame parameter. */
4455
4456static void
4457handle_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val,
4458 Lisp_Object old_value)
4459{
4460 Lisp_Object param_index = Fget (prop, Qx_frame_parameter);
4461 if (FIXNATP (param_index) && XFIXNAT (param_index) < ARRAYELTS (frame_parms))
4462 {
4463 if (FRAME_RIF (f))
4464 {
4465 frame_parm_handler handler
4466 = FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (param_index)];
4467 if (handler)
4468 handler (f, val, old_value);
4469 }
4470 }
4471}
4472
4249/* Change the parameters of frame F as specified by ALIST. 4473/* Change the parameters of frame F as specified by ALIST.
4250 If a parameter is not specially recognized, do nothing special; 4474 If a parameter is not specially recognized, do nothing special;
4251 otherwise call the `gui_set_...' function for that parameter. 4475 otherwise call the `gui_set_...' function for that parameter.
@@ -4387,17 +4611,9 @@ gui_set_frame_parameters_1 (struct frame *f, Lisp_Object alist,
4387 } 4611 }
4388 else 4612 else
4389 { 4613 {
4390 Lisp_Object param_index, old_value; 4614 Lisp_Object old_value = get_frame_param (f, prop);
4391
4392 old_value = get_frame_param (f, prop);
4393
4394 store_frame_param (f, prop, val); 4615 store_frame_param (f, prop, val);
4395 4616 handle_frame_param (f, prop, val, old_value);
4396 param_index = Fget (prop, Qx_frame_parameter);
4397 if (FIXNATP (param_index)
4398 && XFIXNAT (param_index) < ARRAYELTS (frame_parms)
4399 && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])
4400 (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value);
4401 4617
4402 if (!default_parameter && EQ (prop, Qfont)) 4618 if (!default_parameter && EQ (prop, Qfont))
4403 /* The user manually specified the `font' frame parameter. 4619 /* The user manually specified the `font' frame parameter.
@@ -4716,14 +4932,7 @@ gui_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_va
4716 /* Apply the new gamma value to the frame background. */ 4932 /* Apply the new gamma value to the frame background. */
4717 bgcolor = Fassq (Qbackground_color, f->param_alist); 4933 bgcolor = Fassq (Qbackground_color, f->param_alist);
4718 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor))) 4934 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
4719 { 4935 handle_frame_param (f, Qbackground_color, bgcolor, Qnil);
4720 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
4721 if (FIXNATP (parm_index)
4722 && XFIXNAT (parm_index) < ARRAYELTS (frame_parms)
4723 && FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4724 (*FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4725 (f, bgcolor, Qnil);
4726 }
4727 4936
4728 clear_face_cache (true); /* FIXME: Why of all frames? */ 4937 clear_face_cache (true); /* FIXME: Why of all frames? */
4729 fset_redisplay (f); 4938 fset_redisplay (f);