X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/37d2e431f35492c14510f9960cac94c2f21b6ecb..f8eb15727ae6a5c629e27ab9755e638766b27822:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 0fa821682f..8eabef55d1 100644 --- a/src/frame.c +++ b/src/frame.c @@ -69,14 +69,12 @@ Lisp_Object Qnoelisp; static Lisp_Object Qx_frame_parameter; Lisp_Object Qx_resource_name; Lisp_Object Qterminal; -Lisp_Object Qterminal_live_p; /* Frame parameters (set or reported). */ Lisp_Object Qauto_raise, Qauto_lower; Lisp_Object Qborder_color, Qborder_width; Lisp_Object Qcursor_color, Qcursor_type; -static Lisp_Object Qgeometry; /* Not used */ Lisp_Object Qheight, Qwidth; Lisp_Object Qleft, Qright; Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; @@ -115,6 +113,8 @@ Lisp_Object Qface_set_after_frame_default; static Lisp_Object Qdelete_frame_functions; +static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; + #ifdef HAVE_WINDOW_SYSTEM static void x_report_frame_params (struct frame *, Lisp_Object *); #endif @@ -149,25 +149,55 @@ decode_any_frame (register Lisp_Object frame) return XFRAME (frame); } +bool +window_system_available (struct frame *f) +{ + if (f) + return FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f); + else +#ifdef HAVE_WINDOW_SYSTEM + return x_display_list != NULL; +#else + return 0; +#endif +} + +struct frame * +decode_window_system_frame (Lisp_Object frame) +{ + struct frame *f = decode_live_frame (frame); + + if (!window_system_available (f)) + error ("Window system frame should be used"); + return f; +} + +void +check_window_system (struct frame *f) +{ + if (!window_system_available (f)) + error (f ? "Window system frame should be used" + : "Window system is not in use or not initialized"); +} + static void set_menu_bar_lines_1 (Lisp_Object window, int n) { struct window *w = XWINDOW (window); - w->last_modified = 0; - wset_top_line (w, make_number (XFASTINT (w->top_line) + n)); - wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n)); + w->top_line += n; + w->total_lines -= n; /* Handle just the top child in a vertical split. */ - if (!NILP (w->vchild)) - set_menu_bar_lines_1 (w->vchild, n); - - /* Adjust all children in a horizontal split. */ - for (window = w->hchild; !NILP (window); window = w->next) - { - w = XWINDOW (window); - set_menu_bar_lines_1 (window, n); - } + if (WINDOW_VERTICAL_COMBINATION_P (w)) + set_menu_bar_lines_1 (w->contents, n); + else if (WINDOW_HORIZONTAL_COMBINATION_P (w)) + /* Adjust all children in a horizontal split. */ + for (window = w->contents; !NILP (window); window = w->next) + { + w = XWINDOW (window); + set_menu_bar_lines_1 (window, n); + } } void @@ -194,7 +224,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) FRAME_WINDOW_SIZES_CHANGED (f) = 1; FRAME_MENU_BAR_LINES (f) = nlines; set_menu_bar_lines_1 (f->root_window, nlines - olines); - adjust_glyphs (f); + adjust_frame_glyphs (f); } } @@ -278,7 +308,7 @@ predicates which report frame's specific UI-related capabilities. */) } struct frame * -make_frame (int mini_p) +make_frame (bool mini_p) { Lisp_Object frame; register struct frame *f; @@ -332,14 +362,14 @@ make_frame (int mini_p) SET_FRAME_COLS (f, 10); FRAME_LINES (f) = 10; - wset_total_cols (XWINDOW (root_window), make_number (10)); - wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10)); + XWINDOW (root_window)->total_cols = 10; + XWINDOW (root_window)->total_lines = mini_p ? 9 : 10; if (mini_p) { - wset_total_cols (XWINDOW (mini_window), make_number (10)); - wset_top_line (XWINDOW (mini_window), make_number (9)); - wset_total_lines (XWINDOW (mini_window), make_number (1)); + XWINDOW (mini_window)->total_cols = 10; + XWINDOW (mini_window)->top_line = 9; + XWINDOW (mini_window)->total_lines = 1; } /* Choose a buffer for the frame's root window. */ @@ -357,7 +387,7 @@ make_frame (int mini_p) etc. Running Lisp functions at this point surely ends in a SEGV. */ set_window_buffer (root_window, buf, 0, 0); - fset_buffer_list (f, Fcons (buf, Qnil)); + fset_buffer_list (f, list1 (buf)); } if (mini_p) @@ -421,7 +451,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis /* Make the chosen minibuffer window display the proper minibuffer, unless it is already showing a minibuffer. */ - if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list))) + if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list))) /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ set_window_buffer (mini_window, @@ -662,24 +692,16 @@ affects all frames on the same terminal device. */) ? FRAME_TTY (XFRAME (selected_frame))->name : NULL)); if (!NILP (tty)) - { - name = alloca (SBYTES (tty) + 1); - memcpy (name, SSDATA (tty), SBYTES (tty)); - name[SBYTES (tty)] = 0; - } + name = xlispstrdupa (tty); tty_type = get_future_frame_param (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) ? FRAME_TTY (XFRAME (selected_frame))->type : NULL)); if (!NILP (tty_type)) - { - type = alloca (SBYTES (tty_type) + 1); - memcpy (type, SSDATA (tty_type), SBYTES (tty_type)); - type[SBYTES (tty_type)] = 0; - } + type = xlispstrdupa (tty_type); - t = init_tty (name, type, 0); /* Errors are not fatal. */ + t = init_tty (name, type, 0); /* Errors are not fatal. */ } f = make_terminal_frame (t); @@ -690,19 +712,16 @@ affects all frames on the same terminal device. */) change_frame_size (f, height, width, 0, 0, 0); } - adjust_glyphs (f); + adjust_frame_glyphs (f); calculate_costs (f); XSETFRAME (frame, f); + + store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); + store_in_alist (&parms, Qtty, + (t->display_info.tty->name + ? build_string (t->display_info.tty->name) + : Qnil)); Fmodify_frame_parameters (frame, parms); - Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type, - build_string (t->display_info.tty->type)), - Qnil)); - if (t->display_info.tty->name != NULL) - Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, - build_string (t->display_info.tty->name)), - Qnil)); - else - Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil)); /* Make the frame face alist be frame-specific, so that each frame could change its face definitions independently. */ @@ -803,10 +822,18 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame))) { - if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame)) - /* Mark previously displayed frame as now obscured. */ - SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2); - SET_FRAME_VISIBLE (XFRAME (frame), 1); + Lisp_Object top_frame = FRAME_TTY (XFRAME (frame))->top_frame; + + /* Don't mark the frame garbaged and/or obscured if we are + switching to the frame that is already the top frame of that + TTY. */ + if (!EQ (frame, top_frame)) + { + if (FRAMEP (top_frame)) + /* Mark previously displayed frame as now obscured. */ + SET_FRAME_VISIBLE (XFRAME (top_frame), 2); + SET_FRAME_VISIBLE (XFRAME (frame), 1); + } FRAME_TTY (XFRAME (frame))->top_frame = frame; } @@ -847,6 +874,26 @@ This function returns FRAME, or nil if FRAME has been deleted. */) return do_switch_frame (frame, 1, 0, norecord); } +DEFUN ("handle-focus-in", Fhandle_focus_in, Shandle_focus_in, 1, 1, "e", + doc: /* Handle a focus-in event. +Focus in events are usually bound to this function. +Focus in events occur when a frame has focus, but a switch-frame event +is not generated. +This function checks if blink-cursor timers should be turned on again. */) + (Lisp_Object event) +{ + return call0 (intern ("blink-cursor-check")); +} + +DEFUN ("handle-focus-out", Fhandle_focus_out, Shandle_focus_out, 1, 1, "e", + doc: /* Handle a focus-out event. +Focus out events are usually bound to this function. +Focus out events occur when no frame has focus. +This function checks if blink-cursor timers should be turned off. */) + (Lisp_Object event) +{ + return call0 (intern ("blink-cursor-suspend")); +} DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e", doc: /* Handle a switch-frame event EVENT. @@ -862,6 +909,7 @@ to that frame. */) /* Preserve prefix arg that the command loop just cleared. */ kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); Frun_hooks (1, &Qmouse_leave_buffer_hook); + Fhandle_focus_in (event); // switch-frame implies a focus in. return do_switch_frame (event, 0, 0, Qnil); } @@ -889,7 +937,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list, /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the same tty (for tty frames) or among frames which uses FRAME's keyboard. If MINIBUF is nil, do not consider minibuffer-only candidate. - If MINIBUF is `visible', do not consider an invisible candidate. + If MINIBUF is `visible', do not consider an invisible candidate. If MINIBUF is a window, consider only its own frame and candidate now using that window as the minibuffer. If MINIBUF is 0, consider candidate if it is visible or iconified. @@ -1030,13 +1078,26 @@ Otherwise, include all frames. */) CHECK_LIVE_FRAME (frame); return prev_frame (frame, miniframe); } + +DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, + Slast_nonminibuf_frame, 0, 0, 0, + doc: /* Return last non-minibuffer frame selected. */) + (void) +{ + Lisp_Object frame = Qnil; + + if (last_nonminibuf_frame) + XSETFRAME (frame, last_nonminibuf_frame); + + return frame; +} /* Return 1 if it is ok to delete frame F; 0 if all frames aside from F are invisible. (Exception: if F is the terminal frame, and we are using X, return 1.) */ static int -other_visible_frames (FRAME_PTR f) +other_visible_frames (struct frame *f) { Lisp_Object frames, this; @@ -1047,7 +1108,7 @@ other_visible_frames (FRAME_PTR f) /* Verify that we can still talk to the frame's X window, and note any recent change in visibility. */ -#ifdef HAVE_WINDOW_SYSTEM +#ifdef HAVE_X_WINDOWS if (FRAME_WINDOW_P (XFRAME (this))) x_sync (XFRAME (this)); #endif @@ -1062,6 +1123,52 @@ other_visible_frames (FRAME_PTR f) return 0; } +/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer + window. Preferably use the selected frame's minibuffer window + instead. If the selected frame doesn't have one, get some other + frame's minibuffer window. SELECT non-zero means select the new + minibuffer window. */ +static void +check_minibuf_window (Lisp_Object frame, int select) +{ + struct frame *f = decode_live_frame (frame); + + XSETFRAME (frame, f); + + if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window)) + { + Lisp_Object frames, this, window = make_number (0); + + if (!EQ (frame, selected_frame) + && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame))) + window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame)); + else + FOR_EACH_FRAME (frames, this) + { + if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this))) + { + window = FRAME_MINIBUF_WINDOW (XFRAME (this)); + break; + } + } + + /* Don't abort if no window was found (Bug#15247). */ + if (WINDOWP (window)) + { + /* Use set_window_buffer instead of Fset_window_buffer (see + discussion of bug#11984, bug#12025, bug#12026). */ + set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0); + minibuf_window = window; + + /* SELECT non-zero usually means that FRAME's minibuffer + window was selected; select the new one. */ + if (select) + Fselect_window (minibuf_window, Qnil); + } + } +} + + /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME unconditionally. x_connection_closed and delete_terminal use this. Any other value of FORCE implements the semantics @@ -1096,10 +1203,14 @@ delete_frame (Lisp_Object frame, Lisp_Object force) FOR_EACH_FRAME (frames, this) { - if (! EQ (this, frame) - && EQ (frame, - WINDOW_FRAME (XWINDOW - (FRAME_MINIBUF_WINDOW (XFRAME (this)))))) + Lisp_Object fminiw; + + if (EQ (this, frame)) + continue; + + fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this)); + + if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw)))) { /* If we MUST delete this frame, delete the other first. But do this only if FORCE equals `noelisp'. */ @@ -1145,10 +1256,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force) /* Don't let the frame remain selected. */ if (f == sf) { - Lisp_Object tail, frame1; - - /* Look for another visible frame on the same terminal. */ - frame1 = next_frame (frame, Qvisible); + Lisp_Object tail; + Lisp_Object frame1 = Qnil; + + /* Look for another visible frame on the same terminal. + Do not call next_frame here because it may loop forever. + See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */ + FOR_EACH_FRAME (tail, frame1) + if (!EQ (frame, frame1) + && (FRAME_TERMINAL (XFRAME (frame)) + == FRAME_TERMINAL (XFRAME (frame1))) + && FRAME_VISIBLE_P (XFRAME (frame1))) + break; /* If there is none, find *some* other frame. */ if (NILP (frame1) || EQ (frame1, frame)) @@ -1184,19 +1303,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) } /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, 0, 0); - minibuf_window = sf->minibuffer_window; - - /* If the dying minibuffer window was selected, - select the new one. */ - if (minibuffer_selected) - Fselect_window (minibuf_window, Qnil); - } + check_minibuf_window (frame, minibuffer_selected); /* Don't let echo_area_window to remain on a deleted frame. */ if (EQ (f->minibuffer_window, echo_area_window)) @@ -1406,7 +1513,7 @@ passing the normal return value to that function as an argument, and returns whatever that function returns. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y, retval; struct gcpro gcpro1; @@ -1452,7 +1559,7 @@ to read the mouse position, it returns the selected frame for FRAME and nil for X and Y. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y; @@ -1593,17 +1700,13 @@ make_frame_visible_1 (Lisp_Object window) { struct window *w; - for (;!NILP (window); window = w->next) + for (; !NILP (window); window = w->next) { w = XWINDOW (window); - - if (!NILP (w->buffer)) - bset_display_time (XBUFFER (w->buffer), Fcurrent_time ()); - - if (!NILP (w->vchild)) - make_frame_visible_1 (w->vchild); - if (!NILP (w->hchild)) - make_frame_visible_1 (w->hchild); + if (WINDOWP (w->contents)) + make_frame_visible_1 (w->contents); + else + bset_display_time (XBUFFER (w->contents), Fcurrent_time ()); } } @@ -1627,16 +1730,8 @@ displayed in the terminal. */) if (NILP (force) && !other_visible_frames (f)) error ("Attempt to make invisible the sole visible or iconified frame"); - /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, 0, 0); - minibuf_window = sf->minibuffer_window; - } + /* Don't allow minibuf_window to remain on an invisible frame. */ + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1659,15 +1754,7 @@ If omitted, FRAME defaults to the currently selected frame. */) struct frame *f = decode_live_frame (frame); /* Don't allow minibuf_window to remain on an iconified frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, 0, 0); - minibuf_window = sf->minibuffer_window; - } + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1814,12 +1901,23 @@ See `redirect-frame-focus'. */) return FRAME_FOCUS_FRAME (decode_live_frame (frame)); } +DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0, + doc: /* Set the input focus to FRAME. +FRAME nil means use the selected frame. +If there is no window system support, this function does nothing. */) + (Lisp_Object frame) +{ +#ifdef HAVE_WINDOW_SYSTEM + x_focus_frame (decode_window_system_frame (frame)); +#endif + return Qnil; +} /* Return the value of frame parameter PROP in frame FRAME. */ #ifdef HAVE_WINDOW_SYSTEM -#if !HAVE_NS +#if !HAVE_NS && !defined (WINDOWSNT) static #endif Lisp_Object @@ -2120,7 +2218,7 @@ If FRAME is nil, describe the currently selected frame. */) value = f->name; #ifdef HAVE_X_WINDOWS else if (EQ (parameter, Qdisplay) && FRAME_X_P (f)) - value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element); + value = XCAR (FRAME_DISPLAY_INFO (f)->name_list_element); #endif /* HAVE_X_WINDOWS */ else if (EQ (parameter, Qbackground_color) || EQ (parameter, Qforeground_color)) @@ -2192,7 +2290,9 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) (Lisp_Object frame, Lisp_Object alist) { struct frame *f = decode_live_frame (frame); - register Lisp_Object tail, prop, val; + register Lisp_Object prop, val; + + CHECK_LIST (alist); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2217,12 +2317,11 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) /* Extract parm names and values into those vectors. */ - i = 0; - for (tail = alist; CONSP (tail); tail = XCDR (tail)) + for (i = 0; CONSP (alist); alist = XCDR (alist)) { Lisp_Object elt; - elt = XCAR (tail); + elt = XCAR (alist); parms[i] = Fcar (elt); values[i] = Fcdr (elt); i++; @@ -2303,7 +2402,7 @@ to `frame-height'). */) #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) - return make_number (x_pixel_height (f)); + return make_number (FRAME_PIXEL_HEIGHT (f)); else #endif return make_number (FRAME_LINES (f)); @@ -2320,7 +2419,7 @@ If FRAME is omitted or nil, the selected frame is used. */) #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) - return make_number (x_pixel_width (f)); + return make_number (FRAME_PIXEL_WIDTH (f)); else #endif return make_number (FRAME_COLS (f)); @@ -2345,8 +2444,9 @@ is used. */) DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0, doc: /* Specify that the frame FRAME has LINES lines. -Optional third arg non-nil means that redisplay should use LINES lines -but that the idea of the actual height of the frame should not be changed. */) +If FRAME is nil, the selected frame is used. Optional third arg +non-nil means that redisplay should use LINES lines but that the +idea of the actual height of the frame should not be changed. */) (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend) { register struct frame *f = decode_live_frame (frame); @@ -2369,8 +2469,9 @@ but that the idea of the actual height of the frame should not be changed. */) DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0, doc: /* Specify that the frame FRAME has COLS columns. -Optional third arg non-nil means that redisplay should use COLS columns -but that the idea of the actual width of the frame should not be changed. */) +If FRAME is nil, the selected frame is used. Optional third arg +non-nil means that redisplay should use COLS columns but that the +idea of the actual width of the frame should not be changed. */) (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) { register struct frame *f = decode_live_frame (frame); @@ -2392,15 +2493,14 @@ but that the idea of the actual width of the frame should not be changed. */) } DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, - doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */) + doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. +If FRAME is nil, the selected frame is used. */) (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows) { - register struct frame *f; + register struct frame *f = decode_live_frame (frame); - CHECK_LIVE_FRAME (frame); CHECK_TYPE_RANGED_INTEGER (int, cols); CHECK_TYPE_RANGED_INTEGER (int, rows); - f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2422,17 +2522,16 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, DEFUN ("set-frame-position", Fset_frame_position, Sset_frame_position, 3, 3, 0, doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET. -This is actually the position of the upper left corner of the frame. -Negative values for XOFFSET or YOFFSET are interpreted relative to -the rightmost or bottommost possible position (that stays within the screen). */) +If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are +actually the position of the upper left corner of the frame. Negative +values for XOFFSET or YOFFSET are interpreted relative to the rightmost +or bottommost possible position (that stays within the screen). */) (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset) { - register struct frame *f; + register struct frame *f = decode_live_frame (frame); - CHECK_LIVE_FRAME (frame); CHECK_TYPE_RANGED_INTEGER (int, xoffset); CHECK_TYPE_RANGED_INTEGER (int, yoffset); - f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2510,7 +2609,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int { int newwidth = FRAME_COLS (f); int newheight = FRAME_LINES (f); - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); *top_pos = f->top_pos; *left_pos = f->left_pos; @@ -2552,7 +2651,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int to store the new value in the parameter alist. */ void -x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) +x_set_frame_parameters (struct frame *f, Lisp_Object alist) { Lisp_Object tail; @@ -2571,9 +2670,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) Lisp_Object *parms; Lisp_Object *values; ptrdiff_t i, p; - int left_no_change = 0, top_no_change = 0; - int icon_left_no_change = 0, icon_top_no_change = 0; - int size_changed = 0; + bool left_no_change = 0, top_no_change = 0; + bool icon_left_no_change = 0, icon_top_no_change = 0; + bool size_changed = 0; struct gcpro gcpro1, gcpro2; i = 0; @@ -2695,7 +2794,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) { left_no_change = 1; if (f->left_pos < 0) - left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil)); + left = list2 (Qplus, make_number (f->left_pos)); else XSETINT (left, f->left_pos); } @@ -2703,7 +2802,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) { top_no_change = 1; if (f->top_pos < 0) - top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil)); + top = list2 (Qplus, make_number (f->top_pos)); else XSETINT (top, f->top_pos); } @@ -2809,10 +2908,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) /* Actually set that position, and convert to absolute. */ x_set_offset (f, leftpos, toppos, -1); } - +#ifdef HAVE_X_WINDOWS if ((!NILP (icon_left) || !NILP (icon_top)) && ! (icon_left_no_change && icon_top_no_change)) x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); +#endif /* HAVE_X_WINDOWS */ } UNGCPRO; @@ -2838,13 +2938,13 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) if (f->left_pos >= 0) store_in_alist (alistptr, Qleft, tem); else - store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); + store_in_alist (alistptr, Qleft, list2 (Qplus, tem)); XSETINT (tem, f->top_pos); if (f->top_pos >= 0) store_in_alist (alistptr, Qtop, tem); else - store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); + store_in_alist (alistptr, Qtop, list2 (Qplus, tem)); store_in_alist (alistptr, Qborder_width, make_number (f->border_width)); @@ -2884,12 +2984,12 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) (FRAME_VISIBLE_P (f) ? Qt : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); store_in_alist (alistptr, Qdisplay, - XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); + XCAR (FRAME_DISPLAY_INFO (f)->name_list_element)); - if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) + if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_DISPLAY_INFO (f)->root_window) tem = Qnil; else - XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); + tem = make_natnum ((uintptr_t) FRAME_X_OUTPUT (f)->parent_desc); store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil)); store_in_alist (alistptr, Qparent_id, tem); store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position); @@ -2928,6 +3028,15 @@ x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu f->extra_line_spacing = 0; else if (RANGED_INTEGERP (0, new_value, INT_MAX)) f->extra_line_spacing = XFASTINT (new_value); + else if (FLOATP (new_value)) + { + int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5; + + if (new_spacing >= 0) + f->extra_line_spacing = new_spacing; + else + signal_error ("Invalid line-spacing", new_value); + } else signal_error ("Invalid line-spacing", new_value); if (FRAME_VISIBLE_P (f)) @@ -3260,9 +3369,6 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) else if (RANGED_INTEGERP (1, arg, INT_MAX) && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) { - if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) - XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1); - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; if (FRAME_X_WINDOW (f)) @@ -3280,7 +3386,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Return non-nil if frame F wants a bitmap icon. */ Lisp_Object -x_icon_type (FRAME_PTR f) +x_icon_type (struct frame *f) { Lisp_Object tem; @@ -3315,16 +3421,15 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval) else if (FLOATP (item)) { alpha = XFLOAT_DATA (item); - if (alpha < 0.0 || 1.0 < alpha) + if (! (0 <= alpha && alpha <= 1.0)) args_out_of_range (make_float (0.0), make_float (1.0)); } else if (INTEGERP (item)) { EMACS_INT ialpha = XINT (item); - if (ialpha < 0 || 100 < ialpha) + if (! (0 <= ialpha && alpha <= 100)) args_out_of_range (make_number (0), make_number (100)); - else - alpha = ialpha / 100.0; + alpha = ialpha / 100.0; } else wrong_type_argument (Qnumberp, item); @@ -3478,7 +3583,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li value = x_get_string_resource (rdb, name_key, class_key); - if (value != (char *) 0 && *value) + if (value && *value) return build_string (value); else return Qnil; @@ -3495,11 +3600,10 @@ The optional arguments COMPONENT and SUBCLASS add to the key and the class, respectively. You must specify both of them or neither. If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE' and the class is `Emacs.CLASS.SUBCLASS'. */) - (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) + (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, + Lisp_Object subclass) { -#ifdef HAVE_X_WINDOWS - check_x (); -#endif + check_window_system (NULL); return xrdb_get_resource (check_x_display_info (Qnil)->xrdb, attribute, class, component, subclass); @@ -3508,7 +3612,9 @@ and the class is `Emacs.CLASS.SUBCLASS'. */) /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */ Lisp_Object -display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) +display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, + Lisp_Object class, Lisp_Object component, + Lisp_Object subclass) { return xrdb_get_resource (dpyinfo->xrdb, attribute, class, component, subclass); @@ -3533,7 +3639,7 @@ x_get_resource_string (const char *attribute, const char *class) esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); sprintf (class_key, "%s.%s", EMACS_CLASS, class); - result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, + result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb, name_key, class_key); SAFE_FREE (); return result; @@ -3655,7 +3761,7 @@ x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param, const char *attribute, const char *class, enum resource_types type) { - return x_get_arg (FRAME_X_DISPLAY_INFO (f), + return x_get_arg (FRAME_DISPLAY_INFO (f), alist, param, attribute, class, type); } @@ -3669,7 +3775,7 @@ x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist, { Lisp_Object value; - value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param, + value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param, attribute, class, type); if (! NILP (value) && ! EQ (value, Qunbound)) store_frame_param (f, param, value); @@ -3694,7 +3800,7 @@ x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop, tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type); if (EQ (tem, Qunbound)) tem = deflt; - x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); + x_set_frame_parameters (f, list1 (Fcons (prop, tem))); return tem; } @@ -3826,9 +3932,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */) Lisp_Object element; if (x >= 0 && (geometry & XNegative)) - element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil))); + element = list3 (Qleft, Qminus, make_number (-x)); else if (x < 0 && ! (geometry & XNegative)) - element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil))); + element = list3 (Qleft, Qplus, make_number (x)); else element = Fcons (Qleft, make_number (x)); result = Fcons (element, result); @@ -3839,9 +3945,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */) Lisp_Object element; if (y >= 0 && (geometry & YNegative)) - element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil))); + element = list3 (Qtop, Qminus, make_number (-y)); else if (y < 0 && ! (geometry & YNegative)) - element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil))); + element = list3 (Qtop, Qplus, make_number (y)); else element = Fcons (Qtop, make_number (y)); result = Fcons (element, result); @@ -3868,12 +3974,12 @@ On Nextstep, this just calls `ns-parse-geometry'. */) #define DEFAULT_ROWS 35 #define DEFAULT_COLS 80 -int -x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p) +long +x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) { register Lisp_Object tem0, tem1, tem2; long window_prompting = 0; - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); /* Default values if we fall through. Actually, if that happens we should get @@ -4094,6 +4200,75 @@ selected frame. This is useful when `make-pointer-invisible' is set. */) return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt; } + + +/*********************************************************************** + Multimonitor data + ***********************************************************************/ + +#ifdef HAVE_WINDOW_SYSTEM + +# if (defined HAVE_NS \ + || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR))) +void +free_monitors (struct MonitorInfo *monitors, int n_monitors) +{ + int i; + for (i = 0; i < n_monitors; ++i) + xfree (monitors[i].name); + xfree (monitors); +} +# endif + +Lisp_Object +make_monitor_attribute_list (struct MonitorInfo *monitors, + int n_monitors, + int primary_monitor, + Lisp_Object monitor_frames, + const char *source) +{ + Lisp_Object attributes_list = Qnil; + Lisp_Object primary_monitor_attributes = Qnil; + int i; + + for (i = 0; i < n_monitors; ++i) + { + Lisp_Object geometry, workarea, attributes = Qnil; + struct MonitorInfo *mi = &monitors[i]; + + if (mi->geom.width == 0) continue; + + workarea = list4i (mi->work.x, mi->work.y, + mi->work.width, mi->work.height); + geometry = list4i (mi->geom.x, mi->geom.y, + mi->geom.width, mi->geom.height); + attributes = Fcons (Fcons (Qsource, build_string (source)), + attributes); + attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), + attributes); + attributes = Fcons (Fcons (Qmm_size, + list2i (mi->mm_width, mi->mm_height)), + attributes); + attributes = Fcons (Fcons (Qworkarea, workarea), attributes); + attributes = Fcons (Fcons (Qgeometry, geometry), attributes); + if (mi->name) + attributes = Fcons (Fcons (Qname, make_string (mi->name, + strlen (mi->name))), + attributes); + + if (i == primary_monitor) + primary_monitor_attributes = attributes; + else + attributes_list = Fcons (attributes, attributes_list); + } + + if (!NILP (primary_monitor_attributes)) + attributes_list = Fcons (primary_monitor_attributes, attributes_list); + return attributes_list; +} + +#endif /* HAVE_WINDOW_SYSTEM */ + /*********************************************************************** Initialization @@ -4150,7 +4325,12 @@ syms_of_frame (void) DEFSYM (Qx_frame_parameter, "x-frame-parameter"); DEFSYM (Qterminal, "terminal"); - DEFSYM (Qterminal_live_p, "terminal-live-p"); + + DEFSYM (Qgeometry, "geometry"); + DEFSYM (Qworkarea, "workarea"); + DEFSYM (Qmm_size, "mm-size"); + DEFSYM (Qframes, "frames"); + DEFSYM (Qsource, "source"); #ifdef HAVE_NS DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); @@ -4328,11 +4508,14 @@ automatically. See also `mouse-autoselect-window'. */); defsubr (&Swindow_system); defsubr (&Smake_terminal_frame); defsubr (&Shandle_switch_frame); + defsubr (&Shandle_focus_in); + defsubr (&Shandle_focus_out); defsubr (&Sselect_frame); defsubr (&Sselected_frame); defsubr (&Sframe_list); defsubr (&Snext_frame); defsubr (&Sprevious_frame); + defsubr (&Slast_nonminibuf_frame); defsubr (&Sdelete_frame); defsubr (&Smouse_position); defsubr (&Smouse_pixel_position); @@ -4349,6 +4532,7 @@ automatically. See also `mouse-autoselect-window'. */); defsubr (&Svisible_frame_list); defsubr (&Sraise_frame); defsubr (&Slower_frame); + defsubr (&Sx_focus_frame); defsubr (&Sredirect_frame_focus); defsubr (&Sframe_focus); defsubr (&Sframe_parameters);