X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2526c29004c697b3e85e4a84f51124a9befc4549..03e2c340281efb1250f0c272af85a95d1551436c:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index d90bd4d468..e3c32396f1 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1,5 +1,5 @@ /* Functions for the X window system. - Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation. + Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996 Free Software Foundation. This file is part of GNU Emacs. @@ -15,7 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Completely rewritten by Richard Stallman. */ @@ -35,11 +36,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dispextern.h" #include "keyboard.h" #include "blockinput.h" -#include "paths.h" +#include #ifdef HAVE_X_WINDOWS extern void abort (); +/* On some systems, the character-composition stuff is broken in X11R5. */ +#if defined (HAVE_X11R5) && ! defined (HAVE_X11R6) +#ifdef X11R5_INHIBIT_I18N +#define X_I18N_INHIBITED +#endif +#endif + #ifndef VMS #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */ #include "bitmaps/gray.xbm" @@ -53,8 +61,10 @@ extern void abort (); #ifdef USE_X_TOOLKIT #include +#ifndef USE_MOTIF #include #include +#endif /* USE_MOTIF */ #ifdef USG #undef USG /* ####KLUDGE for Solaris 2.2 and up */ @@ -68,8 +78,9 @@ extern void abort (); #include "../lwlib/lwlib.h" -/* Do the EDITRES protocol if running X11R5 */ -#if (XtSpecificationRelease >= 5) +/* Do the EDITRES protocol if running X11R5 + Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */ +#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES) #define HACK_EDITRES extern void _XEditResCheckMessages (); #endif /* R5 + Athena */ @@ -79,7 +90,7 @@ extern void _XEditResCheckMessages (); extern LWLIB_ID widget_id_tick; /* This is part of a kludge--see lwlib/xlwmenu.c. */ -XFontStruct *xlwmenu_default_font; +extern XFontStruct *xlwmenu_default_font; extern void free_frame_menubar (); #endif /* USE_X_TOOLKIT */ @@ -158,12 +169,12 @@ Lisp_Object Qborder_width; Lisp_Object Qbox; Lisp_Object Qcursor_color; Lisp_Object Qcursor_type; -Lisp_Object Qfont; Lisp_Object Qforeground_color; Lisp_Object Qgeometry; Lisp_Object Qicon_left; Lisp_Object Qicon_top; Lisp_Object Qicon_type; +Lisp_Object Qicon_name; Lisp_Object Qinternal_border_width; Lisp_Object Qleft; Lisp_Object Qmouse_color; @@ -184,7 +195,7 @@ Lisp_Object Qdisplay; /* The below are defined in frame.c. */ extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; -extern Lisp_Object Qunsplittable, Qmenu_bar_lines; +extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle; extern Lisp_Object Vwindow_system_version; @@ -197,10 +208,11 @@ check_x () error ("X windows are not in use or not initialized"); } -/* Nonzero if using X for display. */ +/* Nonzero if we can use mouse menus. + You should not call this unless HAVE_MENUS is defined. */ int -using_x_p () +have_menus_p () { return x_in_use; } @@ -222,7 +234,7 @@ check_x_frame (frame) f = XFRAME (frame); } if (! FRAME_X_P (f)) - error ("non-X frame used"); + error ("Non-X frame used"); return f; } @@ -252,7 +264,7 @@ check_x_display_info (frame) CHECK_LIVE_FRAME (frame, 0); f = XFRAME (frame); if (! FRAME_X_P (f)) - error ("non-X frame used"); + error ("Non-X frame used"); return FRAME_X_DISPLAY_INFO (f); } } @@ -276,16 +288,16 @@ x_window_to_frame (dpyinfo, wdesc) if (!GC_FRAMEP (frame)) continue; f = XFRAME (frame); - if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) + if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) continue; #ifdef USE_X_TOOLKIT - if ((f->display.x->edit_widget - && XtWindow (f->display.x->edit_widget) == wdesc) - || f->display.x->icon_desc == wdesc) + if ((f->output_data.x->edit_widget + && XtWindow (f->output_data.x->edit_widget) == wdesc) + || f->output_data.x->icon_desc == wdesc) return f; #else /* not USE_X_TOOLKIT */ if (FRAME_X_WINDOW (f) == wdesc - || f->display.x->icon_desc == wdesc) + || f->output_data.x->icon_desc == wdesc) return f; #endif /* not USE_X_TOOLKIT */ } @@ -303,7 +315,7 @@ x_any_window_to_frame (dpyinfo, wdesc) { Lisp_Object tail, frame; struct frame *f; - struct x_display *x; + struct x_output *x; for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr) { @@ -311,9 +323,9 @@ x_any_window_to_frame (dpyinfo, wdesc) if (!GC_FRAMEP (frame)) continue; f = XFRAME (frame); - if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) + if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) continue; - x = f->display.x; + x = f->output_data.x; /* This frame matches if the window is any of its widgets. */ if (wdesc == XtWindow (x->widget) || wdesc == XtWindow (x->column_widget) @@ -335,7 +347,7 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc) { Lisp_Object tail, frame; struct frame *f; - struct x_display *x; + struct x_output *x; for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr) { @@ -343,9 +355,9 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc) if (!GC_FRAMEP (frame)) continue; f = XFRAME (frame); - if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) + if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) continue; - x = f->display.x; + x = f->output_data.x; /* This frame matches if the window is any of its widgets. */ if (wdesc == XtWindow (x->widget) || wdesc == XtWindow (x->column_widget) @@ -355,6 +367,33 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc) return 0; } +/* Likewise, but consider only the menu bar widget. */ + +struct frame * +x_menubar_window_to_frame (dpyinfo, wdesc) + struct x_display_info *dpyinfo; + int wdesc; +{ + Lisp_Object tail, frame; + struct frame *f; + struct x_output *x; + + for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr) + { + frame = XCONS (tail)->car; + if (!GC_FRAMEP (frame)) + continue; + f = XFRAME (frame); + if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) + continue; + x = f->output_data.x; + /* Match if the window is this frame's menubar. */ + if (lw_window_is_in_menubar (wdesc, x->menubar_widget)) + return f; + } + return 0; +} + /* Return the frame whose principal (outermost) window is WDESC. If WDESC is some other (smaller) window, we return 0. */ @@ -365,7 +404,7 @@ x_top_window_to_frame (dpyinfo, wdesc) { Lisp_Object tail, frame; struct frame *f; - struct x_display *x; + struct x_output *x; for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr) { @@ -373,16 +412,20 @@ x_top_window_to_frame (dpyinfo, wdesc) if (!GC_FRAMEP (frame)) continue; f = XFRAME (frame); - if (f->display.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) + if (f->output_data.nothing == 1 || FRAME_X_DISPLAY_INFO (f) != dpyinfo) continue; - x = f->display.x; + x = f->output_data.x; /* This frame matches if the window is its topmost widget. */ if (wdesc == XtWindow (x->widget)) return f; +#if 0 /* I don't know why it did this, + but it seems logically wrong, + and it causes trouble for MapNotify events. */ /* Match if the window is this frame's menubar. */ if (x->menubar_widget && wdesc == XtWindow (x->menubar_widget)) return f; +#endif } return 0; } @@ -566,12 +609,14 @@ x_destroy_bitmap (f, id) --dpyinfo->bitmaps[id - 1].refcount; if (dpyinfo->bitmaps[id - 1].refcount == 0) { + BLOCK_INPUT; XFreePixmap (FRAME_X_DISPLAY (f), dpyinfo->bitmaps[id - 1].pixmap); if (dpyinfo->bitmaps[id - 1].file) { free (dpyinfo->bitmaps[id - 1].file); dpyinfo->bitmaps[id - 1].file = NULL; } + UNBLOCK_INPUT; } } } @@ -598,27 +643,7 @@ x_destroy_all_bitmaps (dpyinfo) The name of a parameter, as a Lisp symbol, has an `x-frame-parameter' property which is an integer in Lisp - but can be interpreted as an `enum x_frame_parm' in C. */ - -enum x_frame_parm -{ - X_PARM_FOREGROUND_COLOR, - X_PARM_BACKGROUND_COLOR, - X_PARM_MOUSE_COLOR, - X_PARM_CURSOR_COLOR, - X_PARM_BORDER_COLOR, - X_PARM_ICON_TYPE, - X_PARM_FONT, - X_PARM_BORDER_WIDTH, - X_PARM_INTERNAL_BORDER_WIDTH, - X_PARM_NAME, - X_PARM_AUTORAISE, - X_PARM_AUTOLOWER, - X_PARM_VERT_SCROLL_BAR, - X_PARM_VISIBILITY, - X_PARM_MENU_BAR_LINES -}; - + that is an index in this table. */ struct x_frame_parm_table { @@ -633,6 +658,7 @@ void x_set_cursor_color (); void x_set_border_color (); void x_set_cursor_type (); void x_set_icon_type (); +void x_set_icon_name (); void x_set_font (); void x_set_border_width (); void x_set_internal_border_width (); @@ -643,28 +669,31 @@ void x_set_vertical_scroll_bars (); void x_set_visibility (); void x_set_menu_bar_lines (); void x_set_scroll_bar_width (); +void x_set_title (); void x_set_unsplittable (); static struct x_frame_parm_table x_frame_parms[] = { - "foreground-color", x_set_foreground_color, + "auto-raise", x_set_autoraise, + "auto-lower", x_set_autolower, "background-color", x_set_background_color, - "mouse-color", x_set_mouse_color, - "cursor-color", x_set_cursor_color, "border-color", x_set_border_color, + "border-width", x_set_border_width, + "cursor-color", x_set_cursor_color, "cursor-type", x_set_cursor_type, - "icon-type", x_set_icon_type, "font", x_set_font, - "border-width", x_set_border_width, + "foreground-color", x_set_foreground_color, + "icon-name", x_set_icon_name, + "icon-type", x_set_icon_type, "internal-border-width", x_set_internal_border_width, - "name", x_explicitly_set_name, - "auto-raise", x_set_autoraise, - "auto-lower", x_set_autolower, - "vertical-scroll-bars", x_set_vertical_scroll_bars, - "visibility", x_set_visibility, "menu-bar-lines", x_set_menu_bar_lines, + "mouse-color", x_set_mouse_color, + "name", x_explicitly_set_name, "scroll-bar-width", x_set_scroll_bar_width, + "title", x_set_title, "unsplittable", x_set_unsplittable, + "vertical-scroll-bars", x_set_vertical_scroll_bars, + "visibility", x_set_visibility, }; /* Attach the `x-frame-parameter' properties to @@ -769,18 +798,18 @@ x_set_frame_parameters (f, alist) if (EQ (left, Qunbound)) { left_no_change = 1; - if (f->display.x->left_pos < 0) - left = Fcons (Qplus, Fcons (make_number (f->display.x->left_pos), Qnil)); + if (f->output_data.x->left_pos < 0) + left = Fcons (Qplus, Fcons (make_number (f->output_data.x->left_pos), Qnil)); else - XSETINT (left, f->display.x->left_pos); + XSETINT (left, f->output_data.x->left_pos); } if (EQ (top, Qunbound)) { top_no_change = 1; - if (f->display.x->top_pos < 0) - top = Fcons (Qplus, Fcons (make_number (f->display.x->top_pos), Qnil)); + if (f->output_data.x->top_pos < 0) + top = Fcons (Qplus, Fcons (make_number (f->output_data.x->top_pos), Qnil)); else - XSETINT (top, f->display.x->top_pos); + XSETINT (top, f->output_data.x->top_pos); } /* If one of the icon positions was not set, preserve or default it. */ @@ -801,9 +830,19 @@ x_set_frame_parameters (f, alist) /* Don't die if just one of these was set. */ if (EQ (width, Qunbound)) - XSETINT (width, FRAME_WIDTH (f)); + { + if (FRAME_NEW_WIDTH (f)) + XSETINT (width, FRAME_NEW_WIDTH (f)); + else + XSETINT (width, FRAME_WIDTH (f)); + } if (EQ (height, Qunbound)) - XSETINT (height, FRAME_HEIGHT (f)); + { + if (FRAME_NEW_HEIGHT (f)) + XSETINT (height, FRAME_NEW_HEIGHT (f)); + else + XSETINT (height, FRAME_HEIGHT (f)); + } /* Don't set these parameters unless they've been explicitly specified. The window might be mapped or resized while we're in @@ -821,33 +860,34 @@ x_set_frame_parameters (f, alist) XSETFRAME (frame, f); if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f)) - || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f))) + || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)) + || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f)) Fset_frame_size (frame, width, height); if ((!NILP (left) || !NILP (top)) && ! (left_no_change && top_no_change) - && ! (NUMBERP (left) && XINT (left) == f->display.x->left_pos - && NUMBERP (top) && XINT (top) == f->display.x->top_pos)) + && ! (NUMBERP (left) && XINT (left) == f->output_data.x->left_pos + && NUMBERP (top) && XINT (top) == f->output_data.x->top_pos)) { int leftpos = 0; int toppos = 0; /* Record the signs. */ - f->display.x->size_hint_flags &= ~ (XNegative | YNegative); + f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative); if (EQ (left, Qminus)) - f->display.x->size_hint_flags |= XNegative; + f->output_data.x->size_hint_flags |= XNegative; else if (INTEGERP (left)) { leftpos = XINT (left); if (leftpos < 0) - f->display.x->size_hint_flags |= XNegative; + f->output_data.x->size_hint_flags |= XNegative; } else if (CONSP (left) && EQ (XCONS (left)->car, Qminus) && CONSP (XCONS (left)->cdr) && INTEGERP (XCONS (XCONS (left)->cdr)->car)) { leftpos = - XINT (XCONS (XCONS (left)->cdr)->car); - f->display.x->size_hint_flags |= XNegative; + f->output_data.x->size_hint_flags |= XNegative; } else if (CONSP (left) && EQ (XCONS (left)->car, Qplus) && CONSP (XCONS (left)->cdr) @@ -857,19 +897,19 @@ x_set_frame_parameters (f, alist) } if (EQ (top, Qminus)) - f->display.x->size_hint_flags |= YNegative; + f->output_data.x->size_hint_flags |= YNegative; else if (INTEGERP (top)) { toppos = XINT (top); if (toppos < 0) - f->display.x->size_hint_flags |= YNegative; + f->output_data.x->size_hint_flags |= YNegative; } else if (CONSP (top) && EQ (XCONS (top)->car, Qminus) && CONSP (XCONS (top)->cdr) && INTEGERP (XCONS (XCONS (top)->cdr)->car)) { toppos = - XINT (XCONS (XCONS (top)->cdr)->car); - f->display.x->size_hint_flags |= YNegative; + f->output_data.x->size_hint_flags |= YNegative; } else if (CONSP (top) && EQ (XCONS (top)->car, Qplus) && CONSP (XCONS (top)->cdr) @@ -880,10 +920,10 @@ x_set_frame_parameters (f, alist) /* Store the numeric value of the position. */ - f->display.x->top_pos = toppos; - f->display.x->left_pos = leftpos; + f->output_data.x->top_pos = toppos; + f->output_data.x->left_pos = leftpos; - f->display.x->win_gravity = NorthWestGravity; + f->output_data.x->win_gravity = NorthWestGravity; /* Actually set that position, and convert to absolute. */ x_set_offset (f, leftpos, toppos, -1); @@ -911,37 +951,38 @@ x_real_positions (f, xptr, yptr) the problem that arises when restarting window-managers. */ #ifdef USE_X_TOOLKIT - Window outer = XtWindow (f->display.x->widget); + Window outer = XtWindow (f->output_data.x->widget); #else - Window outer = f->display.x->window_desc; + Window outer = f->output_data.x->window_desc; #endif Window tmp_root_window; Window *tmp_children; int tmp_nchildren; - x_catch_errors (FRAME_X_DISPLAY (f)); while (1) { + x_catch_errors (FRAME_X_DISPLAY (f)); + XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window, - &f->display.x->parent_desc, + &f->output_data.x->parent_desc, &tmp_children, &tmp_nchildren); - xfree (tmp_children); + XFree ((char *) tmp_children); win_x = win_y = 0; /* Find the position of the outside upper-left corner of the inner window, with respect to the outer window. */ - if (f->display.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window) + if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window) { XTranslateCoordinates (FRAME_X_DISPLAY (f), /* From-window, to-window. */ #ifdef USE_X_TOOLKIT - XtWindow (f->display.x->widget), + XtWindow (f->output_data.x->widget), #else - f->display.x->window_desc, + f->output_data.x->window_desc, #endif - f->display.x->parent_desc, + f->output_data.x->parent_desc, /* From-position, to-position. */ 0, 0, &win_x, &win_y, @@ -950,8 +991,8 @@ x_real_positions (f, xptr, yptr) &child); #if 0 /* The values seem to be right without this and wrong with. */ - win_x += f->display.x->border_width; - win_y += f->display.x->border_width; + win_x += f->output_data.x->border_width; + win_y += f->output_data.x->border_width; #endif } @@ -961,13 +1002,16 @@ x_real_positions (f, xptr, yptr) If so, we get an error in XTranslateCoordinates. Detect that and try the whole thing over. */ if (! x_had_errors_p (FRAME_X_DISPLAY (f))) - break; - } + { + x_uncatch_errors (FRAME_X_DISPLAY (f)); + break; + } - x_uncatch_errors (FRAME_X_DISPLAY (f)); + x_uncatch_errors (FRAME_X_DISPLAY (f)); + } - *xptr = f->display.x->left_pos - win_x; - *yptr = f->display.x->top_pos - win_y; + *xptr = f->output_data.x->left_pos - win_x; + *yptr = f->output_data.x->top_pos - win_y; } /* Insert a description of internally-recorded parameters of frame X @@ -985,25 +1029,26 @@ x_report_frame_params (f, alistptr) /* Represent negative positions (off the top or left screen edge) in a way that Fmodify_frame_parameters will understand correctly. */ - XSETINT (tem, f->display.x->left_pos); - if (f->display.x->left_pos >= 0) + XSETINT (tem, f->output_data.x->left_pos); + if (f->output_data.x->left_pos >= 0) store_in_alist (alistptr, Qleft, tem); else store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); - XSETINT (tem, f->display.x->top_pos); - if (f->display.x->top_pos >= 0) + XSETINT (tem, f->output_data.x->top_pos); + if (f->output_data.x->top_pos >= 0) store_in_alist (alistptr, Qtop, tem); else store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); store_in_alist (alistptr, Qborder_width, - make_number (f->display.x->border_width)); + make_number (f->output_data.x->border_width)); store_in_alist (alistptr, Qinternal_border_width, - make_number (f->display.x->internal_border_width)); + make_number (f->output_data.x->internal_border_width)); sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); store_in_alist (alistptr, Qwindow_id, build_string (buf)); + store_in_alist (alistptr, Qicon_name, f->icon_name); FRAME_SAMPLE_VISIBILITY (f); store_in_alist (alistptr, Qvisibility, (FRAME_VISIBLE_P (f) ? Qt @@ -1077,8 +1122,16 @@ defined_color (f, color, color_def, alloc) * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); if (trial_delta < nearest_delta) { - nearest = x; - nearest_delta = trial_delta; + XColor temp; + temp.red = cells[x].red; + temp.green = cells[x].green; + temp.blue = cells[x].blue; + status = XAllocColor (display, screen_colormap, &temp); + if (status) + { + nearest = x; + nearest_delta = trial_delta; + } } } color_def->red = cells[nearest].red; @@ -1123,8 +1176,8 @@ x_decode_color (f, arg, def) if (defined_color (f, XSTRING (arg)->data, &cdef, 1)) return cdef.pixel; - /* defined_color failed; return an ultimate default. */ - return def; + Fsignal (Qerror, Fcons (build_string ("undefined color"), + Fcons (arg, Qnil))); } /* Functions called only from `x_set_frame_param' @@ -1140,15 +1193,15 @@ x_set_foreground_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { - f->display.x->foreground_pixel + f->output_data.x->foreground_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; - XSetForeground (FRAME_X_DISPLAY (f), f->display.x->normal_gc, - f->display.x->foreground_pixel); - XSetBackground (FRAME_X_DISPLAY (f), f->display.x->reverse_gc, - f->display.x->foreground_pixel); + XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, + f->output_data.x->foreground_pixel); + XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, + f->output_data.x->foreground_pixel); UNBLOCK_INPUT; recompute_basic_faces (f); if (FRAME_VISIBLE_P (f)) @@ -1164,28 +1217,28 @@ x_set_background_color (f, arg, oldval) Pixmap temp; int mask; - f->display.x->background_pixel + f->output_data.x->background_pixel = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f)); if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; /* The main frame area. */ - XSetBackground (FRAME_X_DISPLAY (f), f->display.x->normal_gc, - f->display.x->background_pixel); - XSetForeground (FRAME_X_DISPLAY (f), f->display.x->reverse_gc, - f->display.x->background_pixel); - XSetForeground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc, - f->display.x->background_pixel); + XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, + f->output_data.x->background_pixel); + XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, + f->output_data.x->background_pixel); + XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, + f->output_data.x->background_pixel); XSetWindowBackground (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->background_pixel); + f->output_data.x->background_pixel); { Lisp_Object bar; for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = XSCROLL_BAR (bar)->next) XSetWindowBackground (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)), - f->display.x->background_pixel); + f->output_data.x->background_pixel); } UNBLOCK_INPUT; @@ -1205,13 +1258,13 @@ x_set_mouse_color (f, arg, oldval) int mask_color; if (!EQ (Qnil, arg)) - f->display.x->mouse_pixel + f->output_data.x->mouse_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); - mask_color = f->display.x->background_pixel; + mask_color = f->output_data.x->background_pixel; /* No invisible pointers. */ - if (mask_color == f->display.x->mouse_pixel - && mask_color == f->display.x->background_pixel) - f->display.x->mouse_pixel = f->display.x->foreground_pixel; + if (mask_color == f->output_data.x->mouse_pixel + && mask_color == f->output_data.x->background_pixel) + f->output_data.x->mouse_pixel = f->output_data.x->foreground_pixel; BLOCK_INPUT; @@ -1264,7 +1317,7 @@ x_set_mouse_color (f, arg, oldval) { XColor fore_color, back_color; - fore_color.pixel = f->display.x->mouse_pixel; + fore_color.pixel = f->output_data.x->mouse_pixel; back_color.pixel = mask_color; XQueryColor (FRAME_X_DISPLAY (f), DefaultColormap (FRAME_X_DISPLAY (f), @@ -1289,23 +1342,23 @@ x_set_mouse_color (f, arg, oldval) XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); } - if (cursor != f->display.x->text_cursor && f->display.x->text_cursor != 0) - XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->text_cursor); - f->display.x->text_cursor = cursor; + if (cursor != f->output_data.x->text_cursor && f->output_data.x->text_cursor != 0) + XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor); + f->output_data.x->text_cursor = cursor; - if (nontext_cursor != f->display.x->nontext_cursor - && f->display.x->nontext_cursor != 0) - XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->nontext_cursor); - f->display.x->nontext_cursor = nontext_cursor; + if (nontext_cursor != f->output_data.x->nontext_cursor + && f->output_data.x->nontext_cursor != 0) + XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor); + f->output_data.x->nontext_cursor = nontext_cursor; - if (mode_cursor != f->display.x->modeline_cursor - && f->display.x->modeline_cursor != 0) - XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->modeline_cursor); - f->display.x->modeline_cursor = mode_cursor; - if (cross_cursor != f->display.x->cross_cursor - && f->display.x->cross_cursor != 0) - XFreeCursor (FRAME_X_DISPLAY (f), f->display.x->cross_cursor); - f->display.x->cross_cursor = cross_cursor; + if (mode_cursor != f->output_data.x->modeline_cursor + && f->output_data.x->modeline_cursor != 0) + XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor); + f->output_data.x->modeline_cursor = mode_cursor; + if (cross_cursor != f->output_data.x->cross_cursor + && f->output_data.x->cross_cursor != 0) + XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->cross_cursor); + f->output_data.x->cross_cursor = cross_cursor; XFlush (FRAME_X_DISPLAY (f)); UNBLOCK_INPUT; @@ -1322,24 +1375,24 @@ x_set_cursor_color (f, arg, oldval) fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT (f)); else - fore_pixel = f->display.x->background_pixel; - f->display.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + fore_pixel = f->output_data.x->background_pixel; + f->output_data.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); /* Make sure that the cursor color differs from the background color. */ - if (f->display.x->cursor_pixel == f->display.x->background_pixel) + if (f->output_data.x->cursor_pixel == f->output_data.x->background_pixel) { - f->display.x->cursor_pixel = f->display.x->mouse_pixel; - if (f->display.x->cursor_pixel == fore_pixel) - fore_pixel = f->display.x->background_pixel; + f->output_data.x->cursor_pixel = f->output_data.x->mouse_pixel; + if (f->output_data.x->cursor_pixel == fore_pixel) + fore_pixel = f->output_data.x->background_pixel; } - f->display.x->cursor_foreground_pixel = fore_pixel; + f->output_data.x->cursor_foreground_pixel = fore_pixel; if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; - XSetBackground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc, - f->display.x->cursor_pixel); - XSetForeground (FRAME_X_DISPLAY (f), f->display.x->cursor_gc, + XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, + f->output_data.x->cursor_pixel); + XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, fore_pixel); UNBLOCK_INPUT; @@ -1350,7 +1403,7 @@ x_set_cursor_color (f, arg, oldval) } } } - + /* Set the border-color of frame F to value described by ARG. ARG can be a string naming a color. The border-color is used for the border that is drawn by the X server. @@ -1386,9 +1439,9 @@ x_set_border_pixel (f, pix) struct frame *f; int pix; { - f->display.x->border_pixel = pix; + f->output_data.x->border_pixel = pix; - if (FRAME_X_WINDOW (f) != 0 && f->display.x->border_width > 0) + if (FRAME_X_WINDOW (f) != 0 && f->output_data.x->border_width > 0) { Pixmap temp; int mask; @@ -1411,13 +1464,13 @@ x_set_cursor_type (f, arg, oldval) if (EQ (arg, Qbar)) { FRAME_DESIRED_CURSOR (f) = bar_cursor; - f->display.x->cursor_width = 2; + f->output_data.x->cursor_width = 2; } else if (CONSP (arg) && EQ (XCONS (arg)->car, Qbar) && INTEGERP (XCONS (arg)->cdr)) { FRAME_DESIRED_CURSOR (f) = bar_cursor; - f->display.x->cursor_width = XINT (XCONS (arg)->cdr); + f->output_data.x->cursor_width = XINT (XCONS (arg)->cdr); } else /* Treat anything unknown as "box cursor". @@ -1429,7 +1482,7 @@ x_set_cursor_type (f, arg, oldval) often do people change cursor types? */ update_mode_lines++; } - + void x_set_icon_type (f, arg, oldval) struct frame *f; @@ -1448,7 +1501,10 @@ x_set_icon_type (f, arg, oldval) BLOCK_INPUT; if (NILP (arg)) - result = x_text_icon (f, 0); + result = x_text_icon (f, + (char *) XSTRING ((!NILP (f->icon_name) + ? f->icon_name + : f->name))->data); else result = x_bitmap_icon (f, arg); @@ -1458,16 +1514,6 @@ x_set_icon_type (f, arg, oldval) error ("No icon window available"); } - /* If the window was unmapped (and its icon was mapped), - the new icon is not mapped, so map the window in its stead. */ - if (FRAME_VISIBLE_P (f)) - { -#ifdef USE_X_TOOLKIT - XtPopup (f->display.x->widget, XtGrabNone); -#endif - XMapWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); - } - XFlush (FRAME_X_DISPLAY (f)); UNBLOCK_INPUT; } @@ -1487,6 +1533,46 @@ x_icon_type (f) return Qnil; } +void +x_set_icon_name (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + Lisp_Object tem; + int result; + + if (STRINGP (arg)) + { + if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt)) + return; + } + else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil)) + return; + + f->icon_name = arg; + + if (f->output_data.x->icon_bitmap != 0) + return; + + BLOCK_INPUT; + + result = x_text_icon (f, + (char *) XSTRING ((!NILP (f->icon_name) + ? f->icon_name + : !NILP (f->title) + ? f->title + : f->name))->data); + + if (result) + { + UNBLOCK_INPUT; + error ("No icon window available"); + } + + XFlush (FRAME_X_DISPLAY (f)); + UNBLOCK_INPUT; +} + extern Lisp_Object x_new_font (); void @@ -1503,7 +1589,7 @@ x_set_font (f, arg, oldval) UNBLOCK_INPUT; if (EQ (result, Qnil)) - error ("Font \"%s\" is not defined", XSTRING (arg)->data); + error ("Font `%s' is not defined", XSTRING (arg)->data); else if (EQ (result, Qt)) error ("the characters of the given font have varying widths"); else if (STRINGP (result)) @@ -1522,13 +1608,13 @@ x_set_border_width (f, arg, oldval) { CHECK_NUMBER (arg, 0); - if (XINT (arg) == f->display.x->border_width) + if (XINT (arg) == f->output_data.x->border_width) return; if (FRAME_X_WINDOW (f) != 0) error ("Cannot change the border width of a window"); - f->display.x->border_width = XINT (arg); + f->output_data.x->border_width = XINT (arg); } void @@ -1537,14 +1623,14 @@ x_set_internal_border_width (f, arg, oldval) Lisp_Object arg, oldval; { int mask; - int old = f->display.x->internal_border_width; + int old = f->output_data.x->internal_border_width; CHECK_NUMBER (arg, 0); - f->display.x->internal_border_width = XINT (arg); - if (f->display.x->internal_border_width < 0) - f->display.x->internal_border_width = 0; + f->output_data.x->internal_border_width = XINT (arg); + if (f->output_data.x->internal_border_width < 0) + f->output_data.x->internal_border_width = 0; - if (f->display.x->internal_border_width == old) + if (f->output_data.x->internal_border_width == old) return; if (FRAME_X_WINDOW (f) != 0) @@ -1575,7 +1661,7 @@ x_set_visibility (f, value, oldval) else Fmake_frame_visible (frame); } - + static void x_set_menu_bar_lines_1 (window, n) Lisp_Object window; @@ -1621,20 +1707,26 @@ x_set_menu_bar_lines (f, value, oldval) #ifdef USE_X_TOOLKIT FRAME_MENU_BAR_LINES (f) = 0; if (nlines) - FRAME_EXTERNAL_MENU_BAR (f) = 1; + { + FRAME_EXTERNAL_MENU_BAR (f) = 1; + if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0) + /* Make sure next redisplay shows the menu bar. */ + XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt; + } else { if (FRAME_EXTERNAL_MENU_BAR (f) == 1) free_frame_menubar (f); FRAME_EXTERNAL_MENU_BAR (f) = 0; - f->display.x->menubar_widget = 0; + if (FRAME_X_P (f)) + f->output_data.x->menubar_widget = 0; } #else /* not USE_X_TOOLKIT */ FRAME_MENU_BAR_LINES (f) = nlines; x_set_menu_bar_lines_1 (f->root_window, nlines - olines); #endif /* not USE_X_TOOLKIT */ } - + /* Change the name of frame F to NAME. If NAME is nil, set F's name to x_id_name. @@ -1683,24 +1775,40 @@ x_set_name (f, name, explicit) if (! NILP (Fstring_equal (name, f->name))) return; + f->name = name; + + /* For setting the frame title, the title parameter should override + the name parameter. */ + if (! NILP (f->title)) + name = f->title; + if (FRAME_X_WINDOW (f)) { BLOCK_INPUT; #ifdef HAVE_X11R4 { - XTextProperty text; + XTextProperty text, icon; + Lisp_Object icon_name; + text.value = XSTRING (name)->data; text.encoding = XA_STRING; text.format = 8; text.nitems = XSTRING (name)->size; + + icon_name = (!NILP (f->icon_name) ? f->icon_name : name); + + icon.value = XSTRING (icon_name)->data; + icon.encoding = XA_STRING; + icon.format = 8; + icon.nitems = XSTRING (icon_name)->size; #ifdef USE_X_TOOLKIT XSetWMName (FRAME_X_DISPLAY (f), - XtWindow (f->display.x->widget), &text); - XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->display.x->widget), - &text); + XtWindow (f->output_data.x->widget), &text); + XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), + &icon); #else /* not USE_X_TOOLKIT */ XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text); - XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text); + XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon); #endif /* not USE_X_TOOLKIT */ } #else /* not HAVE_X11R4 */ @@ -1711,8 +1819,6 @@ x_set_name (f, name, explicit) #endif /* not HAVE_X11R4 */ UNBLOCK_INPUT; } - - f->name = name; } /* This function should be called when the user's lisp code has @@ -1736,7 +1842,73 @@ x_implicitly_set_name (f, arg, oldval) { x_set_name (f, arg, 0); } + +/* Change the title of frame F to NAME. + If NAME is nil, use the frame name as the title. + + If EXPLICIT is non-zero, that indicates that lisp code is setting the + name; if NAME is a string, set F's name to NAME and set + F->explicit_name; if NAME is Qnil, then clear F->explicit_name. + + If EXPLICIT is zero, that indicates that Emacs redisplay code is + suggesting a new name, which lisp code should override; if + F->explicit_name is set, ignore the new name; otherwise, set it. */ +void +x_set_title (f, name) + struct frame *f; + Lisp_Object name; +{ + /* Don't change the title if it's already NAME. */ + if (EQ (name, f->title)) + return; + + update_mode_lines = 1; + + f->title = name; + + if (NILP (name)) + name = f->name; + + if (FRAME_X_WINDOW (f)) + { + BLOCK_INPUT; +#ifdef HAVE_X11R4 + { + XTextProperty text, icon; + Lisp_Object icon_name; + + text.value = XSTRING (name)->data; + text.encoding = XA_STRING; + text.format = 8; + text.nitems = XSTRING (name)->size; + + icon_name = (!NILP (f->icon_name) ? f->icon_name : name); + + icon.value = XSTRING (icon_name)->data; + icon.encoding = XA_STRING; + icon.format = 8; + icon.nitems = XSTRING (icon_name)->size; +#ifdef USE_X_TOOLKIT + XSetWMName (FRAME_X_DISPLAY (f), + XtWindow (f->output_data.x->widget), &text); + XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), + &icon); +#else /* not USE_X_TOOLKIT */ + XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text); + XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon); +#endif /* not USE_X_TOOLKIT */ + } +#else /* not HAVE_X11R4 */ + XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + XSTRING (name)->data); + XStoreName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + XSTRING (name)->data); +#endif /* not HAVE_X11R4 */ + UNBLOCK_INPUT; + } +} + void x_set_autoraise (f, arg, oldval) struct frame *f; @@ -1792,7 +1964,7 @@ x_set_scroll_bar_width (f, arg, oldval) else if (INTEGERP (arg) && XINT (arg) > 0 && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f)) { - int wid = FONT_WIDTH (f->display.x->font); + int wid = FONT_WIDTH (f->output_data.x->font); FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg); FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; if (FRAME_X_WINDOW (f)) @@ -2164,8 +2336,8 @@ x_figure_window_size (f, parms) f->height = DEFAULT_ROWS; /* Window managers expect that if program-specified positions are not (0,0), they're intentional, not defaults. */ - f->display.x->top_pos = 0; - f->display.x->left_pos = 0; + f->output_data.x->top_pos = 0; + f->output_data.x->left_pos = 0; tem0 = x_get_arg (parms, Qheight, 0, 0, number); tem1 = x_get_arg (parms, Qwidth, 0, 0, number); @@ -2188,14 +2360,14 @@ x_figure_window_size (f, parms) window_prompting |= PSize; } - f->display.x->vertical_scroll_bar_extra + f->output_data.x->vertical_scroll_bar_extra = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f) ? 0 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f) - : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->display.x->font))); - f->display.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width); - f->display.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height); + : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font))); + f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width); + f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height); tem0 = x_get_arg (parms, Qtop, 0, 0, number); tem1 = x_get_arg (parms, Qleft, 0, 0, number); @@ -2204,57 +2376,57 @@ x_figure_window_size (f, parms) { if (EQ (tem0, Qminus)) { - f->display.x->top_pos = 0; + f->output_data.x->top_pos = 0; window_prompting |= YNegative; } else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qminus) && CONSP (XCONS (tem0)->cdr) && INTEGERP (XCONS (XCONS (tem0)->cdr)->car)) { - f->display.x->top_pos = - XINT (XCONS (XCONS (tem0)->cdr)->car); + f->output_data.x->top_pos = - XINT (XCONS (XCONS (tem0)->cdr)->car); window_prompting |= YNegative; } else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qplus) && CONSP (XCONS (tem0)->cdr) && INTEGERP (XCONS (XCONS (tem0)->cdr)->car)) { - f->display.x->top_pos = XINT (XCONS (XCONS (tem0)->cdr)->car); + f->output_data.x->top_pos = XINT (XCONS (XCONS (tem0)->cdr)->car); } else if (EQ (tem0, Qunbound)) - f->display.x->top_pos = 0; + f->output_data.x->top_pos = 0; else { CHECK_NUMBER (tem0, 0); - f->display.x->top_pos = XINT (tem0); - if (f->display.x->top_pos < 0) + f->output_data.x->top_pos = XINT (tem0); + if (f->output_data.x->top_pos < 0) window_prompting |= YNegative; } if (EQ (tem1, Qminus)) { - f->display.x->left_pos = 0; + f->output_data.x->left_pos = 0; window_prompting |= XNegative; } else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qminus) && CONSP (XCONS (tem1)->cdr) && INTEGERP (XCONS (XCONS (tem1)->cdr)->car)) { - f->display.x->left_pos = - XINT (XCONS (XCONS (tem1)->cdr)->car); + f->output_data.x->left_pos = - XINT (XCONS (XCONS (tem1)->cdr)->car); window_prompting |= XNegative; } else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qplus) && CONSP (XCONS (tem1)->cdr) && INTEGERP (XCONS (XCONS (tem1)->cdr)->car)) { - f->display.x->left_pos = XINT (XCONS (XCONS (tem1)->cdr)->car); + f->output_data.x->left_pos = XINT (XCONS (XCONS (tem1)->cdr)->car); } else if (EQ (tem1, Qunbound)) - f->display.x->left_pos = 0; + f->output_data.x->left_pos = 0; else { CHECK_NUMBER (tem1, 0); - f->display.x->left_pos = XINT (tem1); - if (f->display.x->left_pos < 0) + f->output_data.x->left_pos = XINT (tem1); + if (f->output_data.x->left_pos < 0) window_prompting |= XNegative; } @@ -2385,12 +2557,12 @@ x_window (f, window_prompting, minibuffer_only) XtSetArg (al[ac], XtNallowShellResize, 1); ac++; XtSetArg (al[ac], XtNinput, 1); ac++; XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++; - XtSetArg (al[ac], XtNborderWidth, f->display.x->border_width); ac++; + XtSetArg (al[ac], XtNborderWidth, f->output_data.x->border_width); ac++; shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS, - topLevelShellWidgetClass, + applicationShellWidgetClass, FRAME_X_DISPLAY (f), al, ac); - f->display.x->widget = shell_widget; + f->output_data.x->widget = shell_widget; /* maybe_set_screen_title_format (shell_widget); */ pane_widget = lw_create_widget ("main", "pane", widget_id_tick++, @@ -2400,7 +2572,7 @@ x_window (f, window_prompting, minibuffer_only) (lw_callback) NULL, (lw_callback) NULL); - f->display.x->column_widget = pane_widget; + f->output_data.x->column_widget = pane_widget; /* mappedWhenManaged to false tells to the paned window to not map/unmap the emacs screen when changing menubar. This reduces flickering. */ @@ -2414,12 +2586,9 @@ x_window (f, window_prompting, minibuffer_only) frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass, pane_widget, al, ac); - lw_set_main_areas (pane_widget, f->display.x->menubar_widget, frame_widget); - f->display.x->edit_widget = frame_widget; + f->output_data.x->edit_widget = frame_widget; - if (f->display.x->menubar_widget) - XtManageChild (f->display.x->menubar_widget); XtManageChild (frame_widget); /* Do some needed geometry management. */ @@ -2428,11 +2597,13 @@ x_window (f, window_prompting, minibuffer_only) char *tem, shell_position[32]; Arg al[2]; int ac = 0; + int extra_borders = 0; int menubar_size - = (f->display.x->menubar_widget - ? (f->display.x->menubar_widget->core.height - + f->display.x->menubar_widget->core.border_width) + = (f->output_data.x->menubar_widget + ? (f->output_data.x->menubar_widget->core.height + + f->output_data.x->menubar_widget->core.border_width) : 0); + extern char *lwlib_toolkit_type; if (FRAME_EXTERNAL_MENU_BAR (f)) { @@ -2441,7 +2612,14 @@ x_window (f, window_prompting, minibuffer_only) menubar_size += ibw; } - f->display.x->menubar_height = menubar_size; + f->output_data.x->menubar_height = menubar_size; + + /* Motif seems to need this amount added to the sizes + specified for the shell widget. The Athena/Lucid widgets don't. + Both conclusions reached experimentally. -- rms. */ + if (!strcmp (lwlib_toolkit_type, "motif")) + XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth, + &extra_borders, NULL); /* Convert our geometry parameters into a geometry string and specify it. @@ -2449,9 +2627,9 @@ x_window (f, window_prompting, minibuffer_only) is a user-specified or program-specified one. We pass that information later, in x_wm_set_size_hints. */ { - int left = f->display.x->left_pos; + int left = f->output_data.x->left_pos; int xneg = window_prompting & XNegative; - int top = f->display.x->top_pos; + int top = f->output_data.x->top_pos; int yneg = window_prompting & YNegative; if (xneg) left = -left; @@ -2459,13 +2637,15 @@ x_window (f, window_prompting, minibuffer_only) top = -top; if (window_prompting & USPosition) - sprintf (shell_position, "=%dx%d%c%d%c%d", PIXEL_WIDTH (f), - PIXEL_HEIGHT (f) + menubar_size, + sprintf (shell_position, "=%dx%d%c%d%c%d", + PIXEL_WIDTH (f) + extra_borders, + PIXEL_HEIGHT (f) + menubar_size + extra_borders, (xneg ? '-' : '+'), left, (yneg ? '-' : '+'), top); else - sprintf (shell_position, "=%dx%d", PIXEL_WIDTH (f), - PIXEL_HEIGHT (f) + menubar_size); + sprintf (shell_position, "=%dx%d", + PIXEL_WIDTH (f) + extra_borders, + PIXEL_HEIGHT (f) + menubar_size + extra_borders); } len = strlen (shell_position) + 1; @@ -2486,10 +2666,41 @@ x_window (f, window_prompting, minibuffer_only) class_hints.res_class = EMACS_CLASS; XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); - f->display.x->wm_hints.input = True; - f->display.x->wm_hints.flags |= InputHint; +#ifdef HAVE_X_I18N +#ifndef X_I18N_INHIBITED + { + XIM xim; + XIC xic = NULL; + + xim = XOpenIM (FRAME_X_DISPLAY (f), NULL, NULL, NULL); + + if (xim) + { + xic = XCreateIC (xim, + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, FRAME_X_WINDOW(f), + XNFocusWindow, FRAME_X_WINDOW(f), + NULL); + + if (xic == 0) + { + XCloseIM (xim); + xim = NULL; + } + } + FRAME_XIM (f) = xim; + FRAME_XIC (f) = xic; + } +#else /* X_I18N_INHIBITED */ + FRAME_XIM (f) = 0; + FRAME_XIC (f) = 0; +#endif /* X_I18N_INHIBITED */ +#endif /* HAVE_X_I18N */ + + f->output_data.x->wm_hints.input = True; + f->output_data.x->wm_hints.flags |= InputHint; XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - &f->display.x->wm_hints); + &f->output_data.x->wm_hints); hack_wm_protocols (f, shell_widget); @@ -2529,12 +2740,13 @@ x_window (f, window_prompting, minibuffer_only) } XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->text_cursor); + f->output_data.x->text_cursor); UNBLOCK_INPUT; if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) initialize_frame_menubar (f); + lw_set_main_areas (pane_widget, f->output_data.x->menubar_widget, frame_widget); if (FRAME_X_WINDOW (f) == 0) error ("Unable to create window"); @@ -2552,8 +2764,8 @@ x_window (f) XSetWindowAttributes attributes; unsigned long attribute_mask; - attributes.background_pixel = f->display.x->background_pixel; - attributes.border_pixel = f->display.x->border_pixel; + attributes.background_pixel = f->output_data.x->background_pixel; + attributes.border_pixel = f->output_data.x->border_pixel; attributes.bit_gravity = StaticGravity; attributes.backing_store = NotUseful; attributes.save_under = True; @@ -2567,15 +2779,46 @@ x_window (f) BLOCK_INPUT; FRAME_X_WINDOW (f) = XCreateWindow (FRAME_X_DISPLAY (f), - f->display.x->parent_desc, - f->display.x->left_pos, - f->display.x->top_pos, + f->output_data.x->parent_desc, + f->output_data.x->left_pos, + f->output_data.x->top_pos, PIXEL_WIDTH (f), PIXEL_HEIGHT (f), - f->display.x->border_width, + f->output_data.x->border_width, CopyFromParent, /* depth */ InputOutput, /* class */ FRAME_X_DISPLAY_INFO (f)->visual, attribute_mask, &attributes); +#ifdef HAVE_X_I18N +#ifndef X_I18N_INHIBITED + { + XIM xim; + XIC xic = NULL; + + xim = XOpenIM (FRAME_X_DISPLAY(f), NULL, NULL, NULL); + + if (xim) + { + xic = XCreateIC (xim, + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, FRAME_X_WINDOW(f), + XNFocusWindow, FRAME_X_WINDOW(f), + NULL); + + if (!xic) + { + XCloseIM (xim); + xim = NULL; + } + } + + FRAME_XIM (f) = xim; + FRAME_XIC (f) = xic; + } +#else /* X_I18N_INHIBITED */ + FRAME_XIM (f) = 0; + FRAME_XIC (f) = 0; +#endif /* X_I18N_INHIBITED */ +#endif /* HAVE_X_I18N */ validate_x_resource_name (); @@ -2585,17 +2828,18 @@ x_window (f) /* The menubar is part of the ordinary display; it does not count in addition to the height of the window. */ - f->display.x->menubar_height = 0; + f->output_data.x->menubar_height = 0; /* This indicates that we use the "Passive Input" input model. Unless we do this, we don't get the Focus{In,Out} events that we need to draw the cursor correctly. Accursed bureaucrats. XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack); */ - f->display.x->wm_hints.input = True; - f->display.x->wm_hints.flags |= InputHint; + f->output_data.x->wm_hints.input = True; + f->output_data.x->wm_hints.flags |= InputHint; XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - &f->display.x->wm_hints); + &f->output_data.x->wm_hints); + f->output_data.x->wm_hints.icon_pixmap = None; /* Request "save yourself" and "delete window" commands from wm. */ { @@ -2620,7 +2864,7 @@ x_window (f) } XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->text_cursor); + f->output_data.x->text_cursor); UNBLOCK_INPUT; @@ -2664,6 +2908,10 @@ x_icon (f, parms) ? IconicState : NormalState)); + x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name) + ? f->icon_name + : f->name))->data); + UNBLOCK_INPUT; } @@ -2693,34 +2941,34 @@ x_make_gc (f) Note that many default values are used. */ /* Normal video */ - gc_values.font = f->display.x->font->fid; - gc_values.foreground = f->display.x->foreground_pixel; - gc_values.background = f->display.x->background_pixel; + gc_values.font = f->output_data.x->font->fid; + gc_values.foreground = f->output_data.x->foreground_pixel; + gc_values.background = f->output_data.x->background_pixel; gc_values.line_width = 0; /* Means 1 using fast algorithm. */ - f->display.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f), + f->output_data.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), GCLineWidth | GCFont | GCForeground | GCBackground, &gc_values); /* Reverse video style. */ - gc_values.foreground = f->display.x->background_pixel; - gc_values.background = f->display.x->foreground_pixel; - f->display.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f), + gc_values.foreground = f->output_data.x->background_pixel; + gc_values.background = f->output_data.x->foreground_pixel; + f->output_data.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), GCFont | GCForeground | GCBackground | GCLineWidth, &gc_values); /* Cursor has cursor-color background, background-color foreground. */ - gc_values.foreground = f->display.x->background_pixel; - gc_values.background = f->display.x->cursor_pixel; + gc_values.foreground = f->output_data.x->background_pixel; + gc_values.background = f->output_data.x->cursor_pixel; gc_values.fill_style = FillOpaqueStippled; gc_values.stipple = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, cursor_bits, 16, 16); - f->display.x->cursor_gc + f->output_data.x->cursor_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), (GCFont | GCForeground | GCBackground | GCFillStyle | GCStipple | GCLineWidth), @@ -2729,12 +2977,12 @@ x_make_gc (f) /* Create the gray border tile used when the pointer is not in the frame. Since this depends on the frame's pixel values, this must be done on a per-frame basis. */ - f->display.x->border_tile + f->output_data.x->border_tile = (XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, gray_bits, gray_width, gray_height, - f->display.x->foreground_pixel, - f->display.x->background_pixel, + f->output_data.x->foreground_pixel, + f->output_data.x->background_pixel, DefaultDepth (FRAME_X_DISPLAY (f), XScreenNumberOfScreen (FRAME_X_SCREEN (f))))); @@ -2762,7 +3010,7 @@ This function is an internal primitive--use `make-frame' instead.") long window_prompting = 0; int width, height; int count = specpdl_ptr - specpdl; - struct gcpro gcpro1; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; Lisp_Object display; struct x_display_info *dpyinfo; Lisp_Object parent; @@ -2774,7 +3022,7 @@ This function is an internal primitive--use `make-frame' instead.") until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; - display = x_get_arg (parms, Qdisplay, 0, 0, 0); + display = x_get_arg (parms, Qdisplay, 0, 0, string); if (EQ (display, Qunbound)) display = Qnil; dpyinfo = check_x_display_info (display); @@ -2784,7 +3032,7 @@ This function is an internal primitive--use `make-frame' instead.") kb = &the_only_kboard; #endif - name = x_get_arg (parms, Qname, "title", "Title", string); + name = x_get_arg (parms, Qname, "name", "Name", string); if (!STRINGP (name) && ! EQ (name, Qunbound) && ! NILP (name)) @@ -2800,6 +3048,11 @@ This function is an internal primitive--use `make-frame' instead.") if (! NILP (parent)) CHECK_NUMBER (parent, 0); + /* make_frame_without_minibuffer can run Lisp code and garbage collect. */ + /* No need to protect DISPLAY because that's not used after passing + it to make_frame_without_minibuffer. */ + frame = Qnil; + GCPRO4 (parms, parent, name, frame); tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol); if (EQ (tem, Qnone) || NILP (tem)) f = make_frame_without_minibuffer (Qnil, kb, display); @@ -2813,16 +3066,20 @@ This function is an internal primitive--use `make-frame' instead.") else f = make_frame (1); + XSETFRAME (frame, f); + /* Note that X Windows does support scroll bars. */ FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; - XSETFRAME (frame, f); - GCPRO1 (frame); - f->output_method = output_x_window; - f->display.x = (struct x_display *) xmalloc (sizeof (struct x_display)); - bzero (f->display.x, sizeof (struct x_display)); - f->display.x->icon_bitmap = -1; + f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output)); + bzero (f->output_data.x, sizeof (struct x_output)); + f->output_data.x->icon_bitmap = -1; + + f->icon_name + = x_get_arg (parms, Qicon_name, "iconName", "Title", string); + if (! STRINGP (f->icon_name)) + f->icon_name = Qnil; FRAME_X_DISPLAY_INFO (f) = dpyinfo; #ifdef MULTI_KBOARD @@ -2833,13 +3090,13 @@ This function is an internal primitive--use `make-frame' instead.") if (!NILP (parent)) { - f->display.x->parent_desc = parent; - f->display.x->explicit_parent = 1; + f->output_data.x->parent_desc = parent; + f->output_data.x->explicit_parent = 1; } else { - f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; - f->display.x->explicit_parent = 0; + f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; + f->output_data.x->explicit_parent = 0; } /* Note that the frame has no physical cursor right now. */ @@ -2893,7 +3150,7 @@ This function is an internal primitive--use `make-frame' instead.") #ifdef USE_X_TOOLKIT /* Prevent lwlib/xlwmenu.c from crashing because of a bug whereby it fails to get any font. */ - xlwmenu_default_font = f->display.x->font; + xlwmenu_default_font = f->output_data.x->font; #endif x_default_parameter (f, parms, Qborder_width, make_number (2), @@ -2932,26 +3189,30 @@ This function is an internal primitive--use `make-frame' instead.") "menuBar", "MenuBar", number); x_default_parameter (f, parms, Qscroll_bar_width, Qnil, "scrollBarWidth", "ScrollBarWidth", number); + x_default_parameter (f, parms, Qbuffer_predicate, Qnil, + "bufferPredicate", "BufferPredicate", symbol); + x_default_parameter (f, parms, Qtitle, Qnil, + "title", "Title", string); - f->display.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; + f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; window_prompting = x_figure_window_size (f, parms); if (window_prompting & XNegative) { if (window_prompting & YNegative) - f->display.x->win_gravity = SouthEastGravity; + f->output_data.x->win_gravity = SouthEastGravity; else - f->display.x->win_gravity = NorthEastGravity; + f->output_data.x->win_gravity = NorthEastGravity; } else { if (window_prompting & YNegative) - f->display.x->win_gravity = SouthWestGravity; + f->output_data.x->win_gravity = SouthWestGravity; else - f->display.x->win_gravity = NorthWestGravity; + f->output_data.x->win_gravity = NorthWestGravity; } - f->display.x->size_hint_flags = window_prompting; + f->output_data.x->size_hint_flags = window_prompting; #ifdef USE_X_TOOLKIT x_window (f, window_prompting, minibuffer_only); @@ -3006,7 +3267,7 @@ This function is an internal primitive--use `make-frame' instead.") /* Make the window appear on the frame and enable display, unless the caller says not to. However, with explicit parent, Emacs cannot control visibility, so don't try. */ - if (! f->display.x->explicit_parent) + if (! f->output_data.x->explicit_parent) { Lisp_Object visibility; @@ -3043,39 +3304,17 @@ x_get_focus_frame (frame) } DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0, - "Set the focus on FRAME.") + "This function is obsolete, and does nothing.") (frame) Lisp_Object frame; { - CHECK_LIVE_FRAME (frame, 0); - - if (FRAME_X_P (XFRAME (frame))) - { - BLOCK_INPUT; - x_focus_on_frame (XFRAME (frame)); - UNBLOCK_INPUT; - return frame; - } - return Qnil; } DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0, - "If a frame has been focused, release it.") + "This function is obsolete, and does nothing.") () { - if (FRAME_X_P (selected_frame)) - { - struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame); - - if (dpyinfo->x_focus_frame) - { - BLOCK_INPUT; - x_unfocus_frame (dpyinfo->x_focus_frame); - UNBLOCK_INPUT; - } - } - return Qnil; } @@ -3124,18 +3363,18 @@ even if they match PATTERN and FACE.") /* Don't die if we get called with a terminal frame. */ if (! FRAME_X_P (f)) - error ("non-X frame used in `x-list-fonts'"); + error ("Non-X frame used in `x-list-fonts'"); face_id = face_name_id_number (f, face); if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f) || FRAME_PARAM_FACES (f) [face_id] == 0) - size_ref = f->display.x->font; + size_ref = f->output_data.x->font; else { size_ref = FRAME_PARAM_FACES (f) [face_id]->font; if (size_ref == (XFontStruct *) (~0)) - size_ref = f->display.x->font; + size_ref = f->output_data.x->font; } } @@ -3162,13 +3401,19 @@ even if they match PATTERN and FACE.") { XFontStruct *thisinfo; - thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), + x_catch_errors (FRAME_X_DISPLAY (f)); + + thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), XSTRING (XCONS (tem)->car)->data); - if (thisinfo && same_size_fonts (thisinfo, size_ref)) + x_check_errors (FRAME_X_DISPLAY (f), "XLoadQueryFont failure: %s"); + x_uncatch_errors (FRAME_X_DISPLAY (f)); + + if (thisinfo && same_size_fonts (thisinfo, size_ref)) newlist = Fcons (XCONS (tem)->car, newlist); - XFreeFont (FRAME_X_DISPLAY (f), thisinfo); + if (thisinfo != 0) + XFreeFont (FRAME_X_DISPLAY (f), thisinfo); } UNBLOCK_INPUT; @@ -3178,6 +3423,8 @@ even if they match PATTERN and FACE.") BLOCK_INPUT; + x_catch_errors (FRAME_X_DISPLAY (f)); + /* Solaris 2.3 has a bug in XListFontsWithInfo. */ #ifndef BROKEN_XLISTFONTSWITHINFO if (size_ref) @@ -3193,6 +3440,9 @@ even if they match PATTERN and FACE.") 2000, /* maxnames */ &num_fonts); /* count_return */ + x_check_errors (FRAME_X_DISPLAY (f), "XListFonts failure: %s"); + x_uncatch_errors (FRAME_X_DISPLAY (f)); + UNBLOCK_INPUT; list = Qnil; @@ -3225,10 +3475,22 @@ even if they match PATTERN and FACE.") XFontStruct *thisinfo; BLOCK_INPUT; + + x_catch_errors (FRAME_X_DISPLAY (f)); thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), names[i]); + x_check_errors (FRAME_X_DISPLAY (f), + "XLoadQueryFont failure: %s"); + x_uncatch_errors (FRAME_X_DISPLAY (f)); + UNBLOCK_INPUT; keeper = thisinfo && same_size_fonts (thisinfo, size_ref); + BLOCK_INPUT; + if (thisinfo && ! keeper) + XFreeFont (FRAME_X_DISPLAY (f), thisinfo); + else if (thisinfo) + XFreeFontInfo (NULL, thisinfo, 1); + UNBLOCK_INPUT; #else keeper = same_size_fonts (&info[i], size_ref); #endif @@ -3325,6 +3587,7 @@ If omitted or nil, that stands for the selected frame's display.") DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0, "Return t if the X display supports shades of gray.\n\ +Note that color displays do support shades of gray.\n\ The optional argument DISPLAY specifies which display to ask about.\n\ DISPLAY should be either a frame or a display name (a string).\n\ If omitted or nil, that stands for the selected frame's display.") @@ -3333,12 +3596,22 @@ If omitted or nil, that stands for the selected frame's display.") { struct x_display_info *dpyinfo = check_x_display_info (display); - if (dpyinfo->n_planes <= 2) + if (dpyinfo->n_planes <= 1) return Qnil; - return (dpyinfo->n_planes > 1 - && (dpyinfo->visual->class == StaticGray - || dpyinfo->visual->class == GrayScale)); + switch (dpyinfo->visual->class) + { + case StaticColor: + case PseudoColor: + case TrueColor: + case DirectColor: + case StaticGray: + case GrayScale: + return Qt; + + default: + return Qnil; + } } DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, @@ -3575,14 +3848,14 @@ int x_char_width (f) register struct frame *f; { - return FONT_WIDTH (f->display.x->font); + return FONT_WIDTH (f->output_data.x->font); } int x_char_height (f) register struct frame *f; { - return f->display.x->line_height; + return f->output_data.x->line_height; } int @@ -3606,19 +3879,19 @@ x_rectangle (f, gc, left_char, top_char, chars, lines) { int width; int height; - int left = (left_char * FONT_WIDTH (f->display.x->font) - + f->display.x->internal_border_width); - int top = (top_char * f->display.x->line_height - + f->display.x->internal_border_width); + int left = (left_char * FONT_WIDTH (f->output_data.x->font) + + f->output_data.x->internal_border_width); + int top = (top_char * f->output_data.x->line_height + + f->output_data.x->internal_border_width); if (chars < 0) - width = FONT_WIDTH (f->display.x->font) / 2; + width = FONT_WIDTH (f->output_data.x->font) / 2; else - width = FONT_WIDTH (f->display.x->font) * chars; + width = FONT_WIDTH (f->output_data.x->font) * chars; if (lines < 0) - height = f->display.x->line_height / 2; + height = f->output_data.x->line_height / 2; else - height = f->display.x->line_height * lines; + height = f->output_data.x->line_height * lines; XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, left, top, width, height); @@ -3666,7 +3939,7 @@ numbers X0, Y0, X1, Y1 in the cursor pixel.") } BLOCK_INPUT; - x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->cursor_gc, + x_rectangle (XFRAME (frame), XFRAME (frame)->output_data.x->cursor_gc, left, top, n_chars, n_lines); UNBLOCK_INPUT; @@ -3715,7 +3988,7 @@ X0, Y0, X1, Y1 in the regular background-pixel.") } BLOCK_INPUT; - x_rectangle (XFRAME (frame), XFRAME (frame)->display.x->reverse_gc, + x_rectangle (XFRAME (frame), XFRAME (frame)->output_data.x->reverse_gc, left, top, n_chars, n_lines); UNBLOCK_INPUT; @@ -3734,9 +4007,9 @@ outline_region (f, gc, top_x, top_y, bottom_x, bottom_y) GC gc; int top_x, top_y, bottom_x, bottom_y; { - register int ibw = f->display.x->internal_border_width; - register int font_w = FONT_WIDTH (f->display.x->font); - register int font_h = f->display.x->line_height; + register int ibw = f->output_data.x->internal_border_width; + register int font_w = FONT_WIDTH (f->output_data.x->font); + register int font_h = f->output_data.x->line_height; int y = top_y; int x = line_len (y); XPoint *pixel_points @@ -3829,18 +4102,18 @@ selected frame.") y1 = f->cursor_y; if (y1 > y0) /* point below mouse */ - outline_region (f, f->display.x->cursor_gc, + outline_region (f, f->output_data.x->cursor_gc, x0, y0, x1, y1); else if (y1 < y0) /* point above mouse */ - outline_region (f, f->display.x->cursor_gc, + outline_region (f, f->output_data.x->cursor_gc, x1, y1, x0, y0); else /* same line: draw horizontal rectangle */ { if (x1 > x0) - x_rectangle (f, f->display.x->cursor_gc, + x_rectangle (f, f->output_data.x->cursor_gc, x0, y0, (x1 - x0 + 1), 1); else if (x1 < x0) - x_rectangle (f, f->display.x->cursor_gc, + x_rectangle (f, f->output_data.x->cursor_gc, x1, y1, (x0 - x1 + 1), 1); } @@ -3866,18 +4139,18 @@ at X, Y on the selected frame.") y1 = f->cursor_y; if (y1 > y0) /* point below mouse */ - outline_region (f, f->display.x->reverse_gc, + outline_region (f, f->output_data.x->reverse_gc, x0, y0, x1, y1); else if (y1 < y0) /* point above mouse */ - outline_region (f, f->display.x->reverse_gc, + outline_region (f, f->output_data.x->reverse_gc, x1, y1, x0, y0); else /* same line: draw horizontal rectangle */ { if (x1 > x0) - x_rectangle (f, f->display.x->reverse_gc, + x_rectangle (f, f->output_data.x->reverse_gc, x0, y0, (x1 - x0 + 1), 1); else if (x1 < x0) - x_rectangle (f, f->display.x->reverse_gc, + x_rectangle (f, f->output_data.x->reverse_gc, x1, y1, (x0 - x1 + 1), 1); } UNBLOCK_INPUT; @@ -3978,13 +4251,13 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e", && x_contour_x > point_x)) { mouse_below_point = 1; - outline_region (f, f->display.x->cursor_gc, point_x, point_y, + outline_region (f, f->output_data.x->cursor_gc, point_x, point_y, x_contour_x, x_contour_y); } else { mouse_below_point = 0; - outline_region (f, f->display.x->cursor_gc, x_contour_x, x_contour_y, + outline_region (f, f->output_data.x->cursor_gc, x_contour_x, x_contour_y, point_x, point_y); } @@ -4000,9 +4273,9 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e", { mouse_below_point = 0; - outline_region (f, f->display.x->reverse_gc, point_x, point_y, + outline_region (f, f->output_data.x->reverse_gc, point_x, point_y, x_contour_x, x_contour_y); - outline_region (f, f->display.x->cursor_gc, x_mouse_x, x_mouse_y, + outline_region (f, f->output_data.x->cursor_gc, x_mouse_x, x_mouse_y, point_x, point_y); } else if (x_mouse_y < x_contour_y) /* Bottom clipped. */ @@ -4023,9 +4296,9 @@ DEFUN ("x-select-region", Fx_select_region, Sx_select_region, 1, 1, "e", { mouse_below_point = 1; - outline_region (f, f->display.x->reverse_gc, + outline_region (f, f->output_data.x->reverse_gc, x_contour_x, x_contour_y, point_x, point_y); - outline_region (f, f->display.x->cursor_gc, point_x, point_y, + outline_region (f, f->output_data.x->cursor_gc, point_x, point_y, x_mouse_x, x_mouse_y); } else if (x_mouse_y > x_contour_y) /* Top clipped. */ @@ -4065,27 +4338,27 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e", register Lisp_Object obj; struct frame *f = selected_frame; register struct window *w = XWINDOW (selected_window); - register GC line_gc = f->display.x->cursor_gc; - register GC erase_gc = f->display.x->reverse_gc; + register GC line_gc = f->output_data.x->cursor_gc; + register GC erase_gc = f->output_data.x->reverse_gc; #if 0 char dash_list[] = {6, 4, 6, 4}; int dashes = 4; XGCValues gc_values; #endif register int previous_y; - register int line = (x_mouse_y + 1) * f->display.x->line_height - + f->display.x->internal_border_width; - register int left = f->display.x->internal_border_width + register int line = (x_mouse_y + 1) * f->output_data.x->line_height + + f->output_data.x->internal_border_width; + register int left = f->output_data.x->internal_border_width + (w->left - * FONT_WIDTH (f->display.x->font)); + * FONT_WIDTH (f->output_data.x->font)); register int right = left + (w->width - * FONT_WIDTH (f->display.x->font)) - - f->display.x->internal_border_width; + * FONT_WIDTH (f->output_data.x->font)) + - f->output_data.x->internal_border_width; #if 0 BLOCK_INPUT; - gc_values.foreground = f->display.x->cursor_pixel; - gc_values.background = f->display.x->background_pixel; + gc_values.foreground = f->output_data.x->cursor_pixel; + gc_values.background = f->output_data.x->background_pixel; gc_values.line_width = 1; gc_values.line_style = LineOnOffDash; gc_values.cap_style = CapRound; @@ -4096,13 +4369,14 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e", | GCLineWidth | GCForeground | GCBackground, &gc_values); XSetDashes (FRAME_X_DISPLAY (f), line_gc, 0, dash_list, dashes); - gc_values.foreground = f->display.x->background_pixel; - gc_values.background = f->display.x->foreground_pixel; + gc_values.foreground = f->output_data.x->background_pixel; + gc_values.background = f->output_data.x->foreground_pixel; erase_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), GCLineStyle | GCJoinStyle | GCCapStyle | GCLineWidth | GCForeground | GCBackground, &gc_values); XSetDashes (FRAME_X_DISPLAY (f), erase_gc, 0, dash_list, dashes); + UNBLOCK_INPUT; #endif while (1) @@ -4112,8 +4386,8 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e", && x_mouse_y < XINT (w->top) + XINT (w->height) - 1) { previous_y = x_mouse_y; - line = (x_mouse_y + 1) * f->display.x->line_height - + f->display.x->internal_border_width; + line = (x_mouse_y + 1) * f->output_data.x->line_height + + f->output_data.x->internal_border_width; XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), line_gc, left, line, right, line); } @@ -4131,12 +4405,12 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e", BLOCK_INPUT; XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), erase_gc, left, line, right, line); - UNBLOCK_INPUT; unread_command_event = obj; #if 0 XFreeGC (FRAME_X_DISPLAY (f), line_gc); XFreeGC (FRAME_X_DISPLAY (f), erase_gc); #endif + UNBLOCK_INPUT; return Qnil; } } @@ -4166,12 +4440,12 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0, BLOCK_INPUT; if (EQ (Vmouse_frame_part, Qtext_part) - && (current_pointer_shape != f->display.x->nontext_cursor)) + && (current_pointer_shape != f->output_data.x->nontext_cursor)) { unsigned char c; struct buffer *buf; - current_pointer_shape = f->display.x->nontext_cursor; + current_pointer_shape = f->output_data.x->nontext_cursor; XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), current_pointer_shape); @@ -4180,9 +4454,9 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 0, 0, 0, c = *(BUF_CHAR_ADDRESS (buf, mouse_buffer_offset)); } else if (EQ (Vmouse_frame_part, Qmodeline_part) - && (current_pointer_shape != f->display.x->modeline_cursor)) + && (current_pointer_shape != f->output_data.x->modeline_cursor)) { - current_pointer_shape = f->display.x->modeline_cursor; + current_pointer_shape = f->output_data.x->modeline_cursor; XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), current_pointer_shape); @@ -4240,7 +4514,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e", /* Erase previous rectangle. */ if (mouse_track_width) { - x_rectangle (f, f->display.x->reverse_gc, + x_rectangle (f, f->output_data.x->reverse_gc, mouse_track_left, mouse_track_top, mouse_track_width, 1); @@ -4320,19 +4594,19 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e", { XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->text_cursor); - x_rectangle (f, f->display.x->cursor_gc, + f->output_data.x->text_cursor); + x_rectangle (f, f->output_data.x->cursor_gc, mouse_track_left, mouse_track_top, mouse_track_width, 1); } else if (in_mode_line) XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->modeline_cursor); + f->output_data.x->modeline_cursor); else XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->nontext_cursor); + f->output_data.x->nontext_cursor); } XFlush (FRAME_X_DISPLAY (f)); @@ -4351,7 +4625,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e", if (mouse_track_width) { - x_rectangle (f, f->display.x->reverse_gc, + x_rectangle (f, f->output_data.x->reverse_gc, mouse_track_left, mouse_track_top, mouse_track_width, 1); mouse_track_width = 0; @@ -4364,7 +4638,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e", } XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->display.x->nontext_cursor); + f->output_data.x->nontext_cursor); XFlush (FRAME_X_DISPLAY (f)); UNBLOCK_INPUT; @@ -4389,7 +4663,7 @@ x_draw_pixmap (f, x, y, image_data, width, height) FRAME_X_WINDOW (f), image_data, width, height); XCopyPlane (FRAME_X_DISPLAY (f), image, FRAME_X_WINDOW (f), - f->display.x->normal_gc, 0, 0, width, height, x, y); + f->output_data.x->normal_gc, 0, 0, width, height, x, y); } #endif @@ -4570,6 +4844,9 @@ x_display_info_for_name (name) CHECK_STRING (name, 0); + if (! EQ (Vwindow_system, intern ("x"))) + error ("Not using X Windows"); + for (dpyinfo = x_display_list, names = x_display_name_list; dpyinfo; dpyinfo = dpyinfo->next, names = XCONS (names)->cdr) @@ -4589,7 +4866,7 @@ x_display_info_for_name (name) (char *) XSTRING (Vx_resource_name)->data); if (dpyinfo == 0) - error ("X server %s not responding", XSTRING (name)->data); + error ("Cannot connect to X server %s", XSTRING (name)->data); x_in_use = 1; XSETFASTINT (Vwindow_system_version, 11); @@ -4614,6 +4891,9 @@ terminate Emacs if we can't open the connection.") if (! NILP (xrm_string)) CHECK_STRING (xrm_string, 1); + if (! EQ (Vwindow_system, intern ("x"))) + error ("Not using X Windows"); + if (! NILP (xrm_string)) xrm_option = (unsigned char *) XSTRING (xrm_string)->data; else @@ -4632,11 +4912,13 @@ terminate Emacs if we can't open the connection.") if (dpyinfo == 0) { if (!NILP (must_succeed)) - fatal ("X server %s not responding.\n\ -Check the DISPLAY environment variable or use \"-d\"\n", + fatal ("Cannot connect to X server %s.\n\ +Check the DISPLAY environment variable or use `-d'.\n\ +Also use the `xhost' program to verify that it is set to permit\n\ +connections from your machine.\n", XSTRING (display)->data); else - error ("X server %s not responding", XSTRING (display)->data); + error ("Cannot connect to X server %s", XSTRING (display)->data); } x_in_use = 1; @@ -4754,8 +5036,6 @@ syms_of_xfns () staticpro (&Qcursor_color); Qcursor_type = intern ("cursor-type"); staticpro (&Qcursor_type); - Qfont = intern ("font"); - staticpro (&Qfont); Qforeground_color = intern ("foreground-color"); staticpro (&Qforeground_color); Qgeometry = intern ("geometry"); @@ -4766,6 +5046,8 @@ syms_of_xfns () staticpro (&Qicon_top); Qicon_type = intern ("icon-type"); staticpro (&Qicon_type); + Qicon_name = intern ("icon-name"); + staticpro (&Qicon_name); Qinternal_border_width = intern ("internal-border-width"); staticpro (&Qinternal_border_width); Qleft = intern ("left"); @@ -4811,7 +5093,7 @@ syms_of_xfns () DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, "List of directories to search for bitmap files for X."); - Vx_bitmap_file_path = Fcons (build_string (PATH_BITMAPS), Qnil); + Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, "The shape of the pointer when over text.\n\ @@ -4856,11 +5138,19 @@ or when you set the mouse color."); Vx_cursor_fore_pixel = Qnil; DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, - "Non-nil if no X window manager is in use."); + "Non-nil if no X window manager is in use.\n\ +Emacs doesn't try to figure this out; this is always nil\n\ +unless you set it to something else."); + /* We don't have any way to find this out, so set it to nil + and maybe the user would like to set it to t. */ + Vx_no_window_manager = Qnil; #ifdef USE_X_TOOLKIT Fprovide (intern ("x-toolkit")); #endif +#ifdef USE_MOTIF + Fprovide (intern ("motif")); +#endif defsubr (&Sx_get_resource); #if 0