X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/af025ae850c8f30431cf79876c4452d9f1679250..844e0de1bc2bf56118b749f50a4880db7c918fd5:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 7699f24fbb..bb10ef9b54 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1,6 +1,6 @@ /* Generic frame functions. -Copyright (C) 1993-1995, 1997, 1999-2013 Free Software Foundation, Inc. +Copyright (C) 1993-1995, 1997, 1999-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -50,6 +50,9 @@ along with GNU Emacs. If not, see . */ #include "msdos.h" #include "dosfns.h" #endif +#ifdef USE_X_TOOLKIT +#include "widget.h" +#endif #ifdef HAVE_NS Lisp_Object Qns_parse_geometry; @@ -125,8 +128,7 @@ Lisp_Object selected_frame; static struct frame *last_nonminibuf_frame; -/* Nonzero means there is at least one garbaged frame. */ - +/* False means there are no visible garbaged frames. */ bool frame_garbaged; #ifdef HAVE_WINDOW_SYSTEM @@ -163,19 +165,16 @@ decode_any_frame (register Lisp_Object frame) return XFRAME (frame); } +#ifdef HAVE_WINDOW_SYSTEM + 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 + return f ? FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f) : x_display_list != NULL; } +#endif /* HAVE_WINDOW_SYSTEM */ + struct frame * decode_window_system_frame (Lisp_Object frame) { @@ -353,6 +352,9 @@ make_frame (bool mini_p) f->line_height = 1; /* !FRAME_WINDOW_P value. */ #ifdef HAVE_WINDOW_SYSTEM f->want_fullscreen = FULLSCREEN_NONE; +#if ! defined (USE_GTK) && ! defined (HAVE_NS) + f->last_tool_bar_item = -1; +#endif #endif root_window = make_window (); @@ -621,7 +623,7 @@ make_terminal_frame (struct terminal *terminal) FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1; FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); - /* Set the top frame to the newly created frame. */ + /* Set the top frame to the newly created frame. */ if (FRAMEP (FRAME_TTY (f)->top_frame) && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */ @@ -1372,10 +1374,11 @@ delete_frame (Lisp_Object frame, Lisp_Object force) { + struct terminal *terminal; block_input (); if (FRAME_TERMINAL (f)->delete_frame_hook) (*FRAME_TERMINAL (f)->delete_frame_hook) (f); - struct terminal *terminal = FRAME_TERMINAL (f); + terminal = FRAME_TERMINAL (f); f->output_data.nothing = 0; f->terminal = 0; /* Now the frame is dead. */ unblock_input (); @@ -1557,7 +1560,7 @@ and returns whatever that function returns. */) GCPRO1 (retval); if (!NILP (Vmouse_position_function)) retval = call1 (Vmouse_position_function, retval); - RETURN_UNGCPRO (retval); + return retval; } DEFUN ("mouse-pixel-position", Fmouse_pixel_position, @@ -1593,6 +1596,42 @@ and nil for X and Y. */) return Fcons (lispy_dummy, Fcons (x, y)); } +#ifdef HAVE_WINDOW_SYSTEM + +/* On frame F, convert character coordinates X and Y to pixel + coordinates *PIX_X and *PIX_Y. */ + +static void +frame_char_to_pixel_position (struct frame *f, int x, int y, + int *pix_x, int *pix_y) +{ + *pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2; + *pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2; + + if (*pix_x < 0) + *pix_x = 0; + if (*pix_x > FRAME_PIXEL_WIDTH (f)) + *pix_x = FRAME_PIXEL_WIDTH (f); + + if (*pix_y < 0) + *pix_y = 0; + if (*pix_y > FRAME_PIXEL_HEIGHT (f)) + *pix_y = FRAME_PIXEL_HEIGHT (f); +} + +/* On frame F, reposition mouse pointer to character coordinates X and Y. */ + +static void +frame_set_mouse_position (struct frame *f, int x, int y) +{ + int pix_x, pix_y; + + frame_char_to_pixel_position (f, x, y, &pix_x, &pix_y); + frame_set_mouse_pixel_position (f, pix_x, pix_y); +} + +#endif /* HAVE_WINDOW_SYSTEM */ + DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0, doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME. Coordinates are relative to the frame, not a window, @@ -1617,7 +1656,7 @@ before calling this function on it, like this. #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) /* Warping the mouse will cause enternotify and focus events. */ - x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y)); + frame_set_mouse_position (XFRAME (frame), XINT (x), XINT (y)); #else #if defined (MSDOS) if (FRAME_MSDOS_P (XFRAME (frame))) @@ -1658,7 +1697,7 @@ before calling this function on it, like this. #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) /* Warping the mouse will cause enternotify and focus events. */ - x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y)); + frame_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y)); #else #if defined (MSDOS) if (FRAME_MSDOS_P (XFRAME (frame))) @@ -1929,9 +1968,6 @@ If there is no window system support, this function does nothing. */) /* Return the value of frame parameter PROP in frame FRAME. */ #ifdef HAVE_WINDOW_SYSTEM -#if !HAVE_NS && !HAVE_NTGUI -static -#endif Lisp_Object get_frame_param (register struct frame *frame, Lisp_Object prop) { @@ -2073,14 +2109,14 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) without messing up the symbol's status. */ if (SYMBOLP (prop)) { - struct Lisp_Symbol *sym = XSYMBOL (prop); + sym_t sym = XSYMBOL (prop); start: - switch (sym->redirect) + switch (SYMBOL_REDIRECT (sym)) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break; case SYMBOL_LOCALIZED: - { struct Lisp_Buffer_Local_Value *blv = sym->val.blv; + { struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); if (blv->frame_local && blv_found (blv) && XFRAME (blv->where) == f) swap_in_global_binding (sym); break; @@ -2515,7 +2551,7 @@ DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0, doc: /* Return scroll bar width of FRAME in pixels. */) (Lisp_Object frame) { - return make_number (decode_any_frame (frame)->scroll_bar_actual_width); + return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame))); } DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0, @@ -2794,7 +2830,8 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) /* If both of these parameters are present, it's more efficient to set them both at once. So we wait until we've looked at the entire list before we set them. */ - int width, height; + int width = 0, height = 0; + bool width_change = 0, height_change = 0; /* Same here. */ Lisp_Object left, top; @@ -2810,7 +2847,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) #ifdef HAVE_X_WINDOWS bool icon_left_no_change = 0, icon_top_no_change = 0; #endif - bool size_changed = 0; struct gcpro gcpro1, gcpro2; i = 0; @@ -2844,18 +2880,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) top = left = Qunbound; icon_left = icon_top = Qunbound; - /* Provide default values for HEIGHT and WIDTH. */ - width = (f->new_width - ? (f->new_pixelwise - ? (f->new_width / FRAME_COLUMN_WIDTH (f)) - : f->new_width) - : FRAME_COLS (f)); - height = (f->new_height - ? (f->new_pixelwise - ? (f->new_height / FRAME_LINE_HEIGHT (f)) - : f->new_height) - : FRAME_LINES (f)); - /* Process foreground_color and background_color before anything else. They are independent of other properties, but other properties (e.g., cursor_color) are dependent upon them. */ @@ -2879,8 +2903,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) param_index = Fget (prop, Qx_frame_parameter); if (NATNUMP (param_index) - && (XFASTINT (param_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (param_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)]) (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); } @@ -2897,13 +2920,13 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX)) { - size_changed = 1; - width = XFASTINT (val); + width_change = 1; + width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ; } else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX)) { - size_changed = 1; - height = XFASTINT (val); + height_change = 1; + height = XFASTINT (val) * FRAME_LINE_HEIGHT (f); } else if (EQ (prop, Qtop)) top = val; @@ -2928,8 +2951,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) param_index = Fget (prop, Qx_frame_parameter); if (NATNUMP (param_index) - && (XFASTINT (param_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (param_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)]) (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); } @@ -2985,15 +3007,34 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) Lisp_Object frame; /* Make this 1, eventually. */ - check_frame_size (f, &width, &height, 0); + check_frame_size (f, &width, &height, 1); XSETFRAME (frame, f); - if (size_changed - && (width != FRAME_COLS (f) - || height != FRAME_LINES (f) + if ((width_change || height_change) + && (width != FRAME_TEXT_WIDTH (f) + || height != FRAME_TEXT_HEIGHT (f) || f->new_height || f->new_width)) - Fset_frame_size (frame, make_number (width), make_number (height), Qnil); + { + /* If necessary provide default values for HEIGHT and WIDTH. Do + that here since otherwise a size change implied by an + intermittent font change may get lost as in Bug#17142. */ + if (!width_change) + width = (f->new_width + ? (f->new_pixelwise + ? f->new_width + : (f->new_width * FRAME_COLUMN_WIDTH (f))) + : FRAME_TEXT_WIDTH (f)); + + if (!height_change) + height = (f->new_height + ? (f->new_pixelwise + ? f->new_height + : (f->new_height * FRAME_LINE_HEIGHT (f))) + : FRAME_TEXT_HEIGHT (f)); + + Fset_frame_size (frame, make_number (width), make_number (height), Qt); + } if ((!NILP (left) || !NILP (top)) && ! (left_no_change && top_no_change) @@ -3221,8 +3262,7 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu { Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter); if (NATNUMP (parm_index) - && (XFASTINT (parm_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (parm_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)]) (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)]) (f, bgcolor, Qnil); @@ -3584,6 +3624,8 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) do_pending_window_change (0); } + /* Eventually remove the following call. It should have been done by + x_set_window_size already. */ change_frame_size (f, 0, 0, 0, 0, 0, 1); XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; @@ -4237,8 +4279,6 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) window_prompting |= PSize; } - f->scroll_bar_actual_width - = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); /* This used to be done _before_ calling x_figure_window_size, but since the height is reset here, this was really a no-op. I @@ -4369,16 +4409,11 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) #endif /* HAVE_WINDOW_SYSTEM */ void -frame_make_pointer_invisible (void) +frame_make_pointer_invisible (struct frame *f) { if (! NILP (Vmake_pointer_invisible)) { - struct frame *f; - if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))) - return; - - f = SELECTED_FRAME (); - if (f && !f->pointer_invisible + if (f && FRAME_LIVE_P (f) && !f->pointer_invisible && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook) { f->mouse_moved = 0; @@ -4389,17 +4424,11 @@ frame_make_pointer_invisible (void) } void -frame_make_pointer_visible (void) +frame_make_pointer_visible (struct frame *f) { /* We don't check Vmake_pointer_invisible here in case the pointer was invisible when Vmake_pointer_invisible was set to nil. */ - struct frame *f; - - if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))) - return; - - f = SELECTED_FRAME (); - if (f && f->pointer_invisible && f->mouse_moved + if (f && FRAME_LIVE_P (f) && f->pointer_invisible && f->mouse_moved && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook) { FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0); @@ -4494,6 +4523,8 @@ make_monitor_attribute_list (struct MonitorInfo *monitors, void syms_of_frame (void) { +#include "frame.x" + DEFSYM (Qframep, "framep"); DEFSYM (Qframe_live_p, "frame-live-p"); DEFSYM (Qexplicit_name, "explicit-name"); @@ -4556,7 +4587,7 @@ syms_of_frame (void) { int i; - for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++) + for (i = 0; i < ARRAYELTS (frame_parms); i++) { Lisp_Object v = intern_c_string (frame_parms[i].name); if (frame_parms[i].variable) @@ -4596,8 +4627,7 @@ is a reasonable practice. See also the variable `x-resource-name'. */); DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit, doc: /* The lower limit of the frame opacity (alpha transparency). The value should range from 0 (invisible) to 100 (completely opaque). -You can also use a floating number between 0.0 and 1.0. -The default is 20. */); +You can also use a floating number between 0.0 and 1.0. */); Vframe_alpha_lower_limit = make_number (20); #endif @@ -4708,7 +4738,6 @@ or call the function `tool-bar-mode'. */); DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, doc: /* Minibufferless frames use this frame's minibuffer. - Emacs cannot create minibufferless frames unless this is set to an appropriate surrogate. @@ -4729,70 +4758,16 @@ automatically. See also `mouse-autoselect-window'. */); focus_follows_mouse = 0; DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise, - doc: /* Non-nil means frames are resized pixelwise. -If this is nil, resizing a frame will round sizes to the frame's -current values of `frame-char-height' and `frame-char-width'. */); + doc: /* Non-nil means resize frames pixelwise. +If this option is nil, resizing a frame rounds its sizes to the frame's +current values of `frame-char-height' and `frame-char-width'. If this +is non-nil, no rounding occurs, hence frame sizes can increase/decrease +by one pixel. + +With some window managers you have to set this to non-nil in order to +fully maximize frames. To resize your initial frame pixelwise, +set this option to a non-nil value in your init file. */); frame_resize_pixelwise = 0; staticpro (&Vframe_list); - - defsubr (&Sframep); - defsubr (&Sframe_live_p); - defsubr (&Swindow_system); - defsubr (&Smake_terminal_frame); - defsubr (&Shandle_switch_frame); - 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); - defsubr (&Sset_mouse_position); - defsubr (&Sset_mouse_pixel_position); -#if 0 - defsubr (&Sframe_configuration); - defsubr (&Srestore_frame_configuration); -#endif - defsubr (&Smake_frame_visible); - defsubr (&Smake_frame_invisible); - defsubr (&Siconify_frame); - defsubr (&Sframe_visible_p); - defsubr (&Svisible_frame_list); - defsubr (&Sraise_frame); - defsubr (&Slower_frame); - defsubr (&Sx_focus_frame); - defsubr (&Sredirect_frame_focus); - defsubr (&Sframe_focus); - defsubr (&Sframe_parameters); - defsubr (&Sframe_parameter); - defsubr (&Smodify_frame_parameters); - defsubr (&Sframe_char_height); - defsubr (&Sframe_char_width); - defsubr (&Sframe_pixel_height); - defsubr (&Sframe_pixel_width); - defsubr (&Sframe_text_cols); - defsubr (&Sframe_text_lines); - defsubr (&Sframe_total_cols); - defsubr (&Sframe_text_width); - defsubr (&Sframe_text_height); - defsubr (&Sscroll_bar_width); - defsubr (&Sfringe_width); - defsubr (&Sborder_width); - defsubr (&Sright_divider_width); - defsubr (&Sbottom_divider_width); - defsubr (&Stool_bar_pixel_width); - defsubr (&Sset_frame_height); - defsubr (&Sset_frame_width); - defsubr (&Sset_frame_size); - defsubr (&Sset_frame_position); - defsubr (&Sframe_pointer_visible_p); - -#ifdef HAVE_WINDOW_SYSTEM - defsubr (&Sx_get_resource); - defsubr (&Sx_parse_geometry); -#endif - }