X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/637ad741e07498dad129b28dc39d7502c8733cea..865203c3b7dbf3c99be9038089a91b459793a165:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index abdb85ccc6..d7097e06a1 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, 1996 Free Software Foundation. + Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation. This file is part of GNU Emacs. @@ -36,7 +36,9 @@ Boston, MA 02111-1307, USA. */ #include "dispextern.h" #include "keyboard.h" #include "blockinput.h" -#include +#include +#include "charset.h" +#include "fontset.h" #ifdef HAVE_X_WINDOWS extern void abort (); @@ -89,8 +91,10 @@ extern void _XEditResCheckMessages (); Library. */ extern LWLIB_ID widget_id_tick; +#ifdef USE_LUCID /* This is part of a kludge--see lwlib/xlwmenu.c. */ -XFontStruct *xlwmenu_default_font; +extern XFontStruct *xlwmenu_default_font; +#endif extern void free_frame_menubar (); #endif /* USE_X_TOOLKIT */ @@ -104,9 +108,13 @@ extern void free_frame_menubar (); #define MAXREQUEST(dpy) ((dpy)->max_request_size) #endif -/* The name we're using in resource queries. */ +/* The name we're using in resource queries. Most often "emacs". */ Lisp_Object Vx_resource_name; +/* The application class we're using in resource queries. + Normally "Emacs". */ +Lisp_Object Vx_resource_class; + /* The background and shape of the mouse pointer, and shape when not over text or in the modeline. */ Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape; @@ -125,6 +133,12 @@ Lisp_Object Vx_no_window_manager; /* Search path for bitmap files. */ Lisp_Object Vx_bitmap_file_path; +/* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */ +Lisp_Object Vx_pixel_size_width_font_regexp; + +/* A flag to control how to display unibyte 8-bit character. */ +int unibyte_display_via_language_environment; + /* Evaluate this expression to rebuild the section of syms_of_xfns that initializes and staticpros the symbols declared below. Note that Emacs 18 has a bug that keeps C-x C-e from being able to @@ -169,7 +183,6 @@ 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; @@ -178,8 +191,10 @@ Lisp_Object Qicon_type; Lisp_Object Qicon_name; Lisp_Object Qinternal_border_width; Lisp_Object Qleft; +Lisp_Object Qright; Lisp_Object Qmouse_color; Lisp_Object Qnone; +Lisp_Object Qouter_window_id; Lisp_Object Qparent_id; Lisp_Object Qscroll_bar_width; Lisp_Object Qsuppress_icon; @@ -200,6 +215,7 @@ extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle; extern Lisp_Object Vwindow_system_version; +Lisp_Object Qface_set_after_frame_default; /* Error if we are not connected to X. */ void @@ -249,7 +265,8 @@ check_x_display_info (frame) { if (NILP (frame)) { - if (FRAME_X_P (selected_frame)) + if (FRAME_X_P (selected_frame) + && FRAME_LIVE_P (selected_frame)) return FRAME_X_DISPLAY_INFO (selected_frame); else if (x_display_list != 0) return x_display_list; @@ -575,6 +592,9 @@ x_create_bitmap_from_file (f, file) fd = openp (Vx_bitmap_file_path, file, "", &found, 0); if (fd < 0) return -1; + /* XReadBitmapFile won't handle magic file names. */ + if (fd == 0) + return -1; close (fd); filename = (char *) XSTRING (found)->data; @@ -587,7 +607,8 @@ x_create_bitmap_from_file (f, file) id = x_allocate_bitmap_record (f); dpyinfo->bitmaps[id - 1].pixmap = bitmap; dpyinfo->bitmaps[id - 1].refcount = 1; - dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1); + dpyinfo->bitmaps[id - 1].file + = (char *) xmalloc (STRING_BYTES (XSTRING (file)) + 1); dpyinfo->bitmaps[id - 1].depth = 1; dpyinfo->bitmaps[id - 1].height = height; dpyinfo->bitmaps[id - 1].width = width; @@ -598,7 +619,7 @@ x_create_bitmap_from_file (f, file) /* Remove reference to bitmap with id number ID. */ -int +void x_destroy_bitmap (f, id) FRAME_PTR f; int id; @@ -700,6 +721,7 @@ static struct x_frame_parm_table x_frame_parms[] = /* Attach the `x-frame-parameter' properties to the Lisp symbol names of parameters relevant to X. */ +void init_x_parm_symbols () { int i; @@ -709,7 +731,7 @@ init_x_parm_symbols () make_number (i)); } -/* Change the parameters of FRAME as specified by ALIST. +/* Change the parameters of frame F as specified by ALIST. If a parameter is not specially recognized, do nothing; otherwise call the `x_set_...' function for that parameter. */ @@ -723,7 +745,7 @@ x_set_frame_parameters (f, 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. */ - Lisp_Object width, height; + int width, height; /* Same here. */ Lisp_Object left, top; @@ -738,6 +760,8 @@ x_set_frame_parameters (f, alist) int left_no_change = 0, top_no_change = 0; int icon_left_no_change = 0, icon_top_no_change = 0; + struct gcpro gcpro1, gcpro2; + i = 0; for (tail = alist; CONSP (tail); tail = Fcdr (tail)) i++; @@ -757,10 +781,29 @@ x_set_frame_parameters (f, alist) values[i] = Fcdr (elt); i++; } + /* TAIL and ALIST are not used again below here. */ + alist = tail = Qnil; + + GCPRO2 (*parms, *values); + gcpro1.nvars = i; + gcpro2.nvars = i; - width = height = top = left = Qunbound; + /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, + because their values appear in VALUES and strings are not valid. */ + top = left = Qunbound; icon_left = icon_top = Qunbound; + /* Provide default values for HEIGHT and WIDTH. */ + if (FRAME_NEW_WIDTH (f)) + width = FRAME_NEW_WIDTH (f); + else + width = FRAME_WIDTH (f); + + if (FRAME_NEW_HEIGHT (f)) + height = FRAME_NEW_HEIGHT (f); + else + height = FRAME_HEIGHT (f); + /* Now process them in reverse of specified order. */ for (i--; i >= 0; i--) { @@ -769,10 +812,10 @@ x_set_frame_parameters (f, alist) prop = parms[i]; val = values[i]; - if (EQ (prop, Qwidth)) - width = val; - else if (EQ (prop, Qheight)) - height = val; + if (EQ (prop, Qwidth) && NUMBERP (val)) + width = XFASTINT (val); + else if (EQ (prop, Qheight) && NUMBERP (val)) + height = XFASTINT (val); else if (EQ (prop, Qtop)) top = val; else if (EQ (prop, Qleft)) @@ -829,22 +872,6 @@ x_set_frame_parameters (f, alist) XSETINT (icon_top, 0); } - /* Don't die if just one of these was set. */ - if (EQ (width, Qunbound)) - { - if (FRAME_NEW_WIDTH (f)) - XSETINT (width, FRAME_NEW_WIDTH (f)); - else - XSETINT (width, FRAME_WIDTH (f)); - } - if (EQ (height, Qunbound)) - { - 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 this function, and we don't want to override that unless the lisp @@ -860,10 +887,10 @@ x_set_frame_parameters (f, alist) XSETFRAME (frame, f); - if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f)) - || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)) + if (width != FRAME_WIDTH (f) + || height != FRAME_HEIGHT (f) || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f)) - Fset_frame_size (frame, width, height); + Fset_frame_size (frame, make_number (width), make_number (height)); if ((!NILP (left) || !NILP (top)) && ! (left_no_change && top_no_change) @@ -934,6 +961,8 @@ x_set_frame_parameters (f, alist) && ! (icon_left_no_change && icon_top_no_change)) x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); } + + UNGCPRO; } /* Store the screen positions of frame F into XPTR and YPTR. @@ -962,7 +991,8 @@ x_real_positions (f, xptr, yptr) while (1) { - x_catch_errors (FRAME_X_DISPLAY (f)); + int count = x_catch_errors (FRAME_X_DISPLAY (f)); + Window outer_window; XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window, &f->output_data.x->parent_desc, @@ -974,28 +1004,21 @@ x_real_positions (f, xptr, yptr) /* Find the position of the outside upper-left corner of the inner window, with respect to the outer window. */ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window) - { - XTranslateCoordinates (FRAME_X_DISPLAY (f), + outer_window = f->output_data.x->parent_desc; + else + outer_window = outer; - /* From-window, to-window. */ -#ifdef USE_X_TOOLKIT - XtWindow (f->output_data.x->widget), -#else - f->output_data.x->window_desc, -#endif - f->output_data.x->parent_desc, + XTranslateCoordinates (FRAME_X_DISPLAY (f), - /* From-position, to-position. */ - 0, 0, &win_x, &win_y, + /* From-window, to-window. */ + outer_window, + FRAME_X_DISPLAY_INFO (f)->root_window, - /* Child of win. */ - &child); + /* From-position, to-position. */ + 0, 0, &win_x, &win_y, -#if 0 /* The values seem to be right without this and wrong with. */ - win_x += f->output_data.x->border_width; - win_y += f->output_data.x->border_width; -#endif - } + /* Child of win. */ + &child); /* It is possible for the window returned by the XQueryNotify to become invalid by the time we call XTranslateCoordinates. @@ -1003,15 +1026,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), count); + break; + } - x_uncatch_errors (FRAME_X_DISPLAY (f)); + x_uncatch_errors (FRAME_X_DISPLAY (f), count); } - x_uncatch_errors (FRAME_X_DISPLAY (f)); - - *xptr = f->output_data.x->left_pos - win_x; - *yptr = f->output_data.x->top_pos - win_y; + *xptr = win_x - f->output_data.x->border_width; + *yptr = win_y - f->output_data.x->border_width; } /* Insert a description of internally-recorded parameters of frame X @@ -1020,6 +1044,7 @@ x_real_positions (f, xptr, yptr) and whose values are not correctly recorded in the frame's param_alist need to be considered here. */ +void x_report_frame_params (f, alistptr) struct frame *f; Lisp_Object *alistptr; @@ -1048,6 +1073,9 @@ x_report_frame_params (f, alistptr) sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); store_in_alist (alistptr, Qwindow_id, build_string (buf)); + sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f)); + store_in_alist (alistptr, Qouter_window_id, + build_string (buf)); store_in_alist (alistptr, Qicon_name, f->icon_name); FRAME_SAMPLE_VISIBILITY (f); store_in_alist (alistptr, Qvisibility, @@ -1055,6 +1083,12 @@ x_report_frame_params (f, alistptr) : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); store_in_alist (alistptr, Qdisplay, XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->car); + + if (f->output_data.x->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) + tem = Qnil; + else + XSETFASTINT (tem, f->output_data.x->parent_desc); + store_in_alist (alistptr, Qparent_id, tem); } @@ -1193,8 +1227,15 @@ x_set_foreground_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { - f->output_data.x->foreground_pixel + unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + + if (f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel + && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel + && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel) + unload_color (f, f->output_data.x->foreground_pixel); + f->output_data.x->foreground_pixel = pixel; + if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; @@ -1217,9 +1258,15 @@ x_set_background_color (f, arg, oldval) Pixmap temp; int mask; - f->output_data.x->background_pixel + unsigned long pixel = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f)); + if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel + && f->output_data.x->background_pixel != f->output_data.x->cursor_pixel + && f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel) + unload_color (f, f->output_data.x->background_pixel); + f->output_data.x->background_pixel = pixel; + if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; @@ -1255,21 +1302,30 @@ x_set_mouse_color (f, arg, oldval) Lisp_Object arg, oldval; { Cursor cursor, nontext_cursor, mode_cursor, cross_cursor; + int count; int mask_color; - + unsigned long pixel = f->output_data.x->mouse_pixel; + if (!EQ (Qnil, arg)) - f->output_data.x->mouse_pixel - = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + mask_color = f->output_data.x->background_pixel; /* No invisible pointers. */ - 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; + if (mask_color == pixel + && mask_color == f->output_data.x->background_pixel) + pixel = f->output_data.x->foreground_pixel; + + if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel + && f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel + && f->output_data.x->cursor_pixel != f->output_data.x->mouse_pixel + && f->output_data.x->cursor_foreground_pixel != f->output_data.x->mouse_pixel) + unload_color (f, f->output_data.x->mouse_pixel); + f->output_data.x->mouse_pixel = pixel; BLOCK_INPUT; /* It's not okay to crash if the user selects a screwy cursor. */ - x_catch_errors (FRAME_X_DISPLAY (f)); + count = x_catch_errors (FRAME_X_DISPLAY (f)); if (!EQ (Qnil, Vx_pointer_shape)) { @@ -1312,7 +1368,7 @@ x_set_mouse_color (f, arg, oldval) /* Check and report errors with the above calls. */ x_check_errors (FRAME_X_DISPLAY (f), "can't set cursor shape: %s"); - x_uncatch_errors (FRAME_X_DISPLAY (f)); + x_uncatch_errors (FRAME_X_DISPLAY (f), count); { XColor fore_color, back_color; @@ -1369,24 +1425,37 @@ x_set_cursor_color (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { - unsigned long fore_pixel; + unsigned long fore_pixel, pixel; if (!EQ (Vx_cursor_fore_pixel, Qnil)) fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT (f)); else fore_pixel = f->output_data.x->background_pixel; - f->output_data.x->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); - + pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); + /* Make sure that the cursor color differs from the background color. */ - if (f->output_data.x->cursor_pixel == f->output_data.x->background_pixel) + if (pixel == f->output_data.x->background_pixel) { - f->output_data.x->cursor_pixel = f->output_data.x->mouse_pixel; - if (f->output_data.x->cursor_pixel == fore_pixel) + pixel = f->output_data.x->mouse_pixel; + if (pixel == fore_pixel) fore_pixel = f->output_data.x->background_pixel; } + + if (f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel + && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel + && f->output_data.x->mouse_pixel != f->output_data.x->cursor_foreground_pixel + && f->output_data.x->cursor_pixel != f->output_data.x->cursor_foreground_pixel) + unload_color (f, f->output_data.x->cursor_foreground_pixel); f->output_data.x->cursor_foreground_pixel = fore_pixel; + if (f->output_data.x->background_pixel != f->output_data.x->cursor_pixel + && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel + && f->output_data.x->mouse_pixel != f->output_data.x->cursor_pixel + && f->output_data.x->cursor_foreground_pixel != f->output_data.x->cursor_pixel) + unload_color (f, f->output_data.x->cursor_pixel); + f->output_data.x->cursor_pixel = pixel; + if (FRAME_X_WINDOW (f) != 0) { BLOCK_INPUT; @@ -1398,8 +1467,8 @@ x_set_cursor_color (f, arg, oldval) if (FRAME_VISIBLE_P (f)) { - x_display_cursor (f, 0); - x_display_cursor (f, 1); + x_update_cursor (f, 0); + x_update_cursor (f, 1); } } } @@ -1435,10 +1504,12 @@ x_set_border_color (f, arg, oldval) Note that this does not fully take effect if done before F has an x-window. */ +void x_set_border_pixel (f, pix) struct frame *f; int pix; { + unload_color (f, f->output_data.x->border_pixel); f->output_data.x->border_pixel = pix; if (FRAME_X_WINDOW (f) != 0 && f->output_data.x->border_width > 0) @@ -1573,19 +1644,23 @@ x_set_icon_name (f, arg, oldval) UNBLOCK_INPUT; } -extern Lisp_Object x_new_font (); - void x_set_font (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { Lisp_Object result; + Lisp_Object fontset_name; + Lisp_Object frame; CHECK_STRING (arg, 1); + fontset_name = Fquery_fontset (arg, Qnil); + BLOCK_INPUT; - result = x_new_font (f, XSTRING (arg)->data); + result = (STRINGP (fontset_name) + ? x_new_fontset (f, XSTRING (fontset_name)->data) + : x_new_font (f, XSTRING (arg)->data)); UNBLOCK_INPUT; if (EQ (result, Qnil)) @@ -1599,6 +1674,9 @@ x_set_font (f, arg, oldval) } else abort (); + + XSETFRAME (frame, f); + call1 (Qface_set_after_frame_default, frame); } void @@ -1630,6 +1708,11 @@ x_set_internal_border_width (f, arg, oldval) if (f->output_data.x->internal_border_width < 0) f->output_data.x->internal_border_width = 0; +#ifdef USE_X_TOOLKIT + if (f->output_data.x->edit_widget) + widget_store_internal_border (f->output_data.x->edit_widget); +#endif + if (f->output_data.x->internal_border_width == old) return; @@ -1704,6 +1787,9 @@ x_set_menu_bar_lines (f, value, oldval) else nlines = 0; + /* Make sure we redisplay all windows in this frame. */ + windows_or_buffers_changed++; + #ifdef USE_X_TOOLKIT FRAME_MENU_BAR_LINES (f) = 0; if (nlines) @@ -1793,14 +1879,14 @@ x_set_name (f, name, explicit) text.value = XSTRING (name)->data; text.encoding = XA_STRING; text.format = 8; - text.nitems = XSTRING (name)->size; + text.nitems = STRING_BYTES (XSTRING (name)); 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; + icon.nitems = STRING_BYTES (XSTRING (icon_name)); #ifdef USE_X_TOOLKIT XSetWMName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), &text); @@ -1869,6 +1955,8 @@ x_set_title (f, name) if (NILP (name)) name = f->name; + else + CHECK_STRING (name, 0); if (FRAME_X_WINDOW (f)) { @@ -1881,14 +1969,14 @@ x_set_title (f, name) text.value = XSTRING (name)->data; text.encoding = XA_STRING; text.format = 8; - text.nitems = XSTRING (name)->size; + text.nitems = STRING_BYTES (XSTRING (name)); 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; + icon.nitems = STRING_BYTES (XSTRING (icon_name)); #ifdef USE_X_TOOLKIT XSetWMName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), &text); @@ -1938,9 +2026,17 @@ x_set_vertical_scroll_bars (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { - if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) + || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) + || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))) { - FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg); + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) + = (NILP (arg) + ? vertical_scroll_bar_none + : EQ (Qright, arg) + ? vertical_scroll_bar_right + : vertical_scroll_bar_left); /* We set this parameter before creating the X window for the frame, so we can get the geometry right from the start. @@ -1956,20 +2052,34 @@ x_set_scroll_bar_width (f, arg, oldval) struct frame *f; Lisp_Object arg, oldval; { + int wid = FONT_WIDTH (f->output_data.x->font); + if (NILP (arg)) { + /* Make the actual width at least 14 pixels + and a multiple of a character width. */ + FRAME_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; + /* Use all of that space (aside from required margins) + for the scroll bar. */ FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = 0; - FRAME_SCROLL_BAR_COLS (f) = 2; + + if (FRAME_X_WINDOW (f)) + x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f)); } else if (INTEGERP (arg) && XINT (arg) > 0 && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f)) { - int wid = FONT_WIDTH (f->output_data.x->font); + if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) + XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1); + FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg); FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; if (FRAME_X_WINDOW (f)) x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f)); } + + change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0); + FRAME_CURSOR_X (f) = FRAME_LEFT_SCROLL_BAR_WIDTH (f); } /* Subroutines of creating an X frame. */ @@ -1988,12 +2098,15 @@ validate_x_resource_name () Lisp_Object new; int i; + if (!STRINGP (Vx_resource_class)) + Vx_resource_class = build_string (EMACS_CLASS); + if (STRINGP (Vx_resource_name)) { unsigned char *p = XSTRING (Vx_resource_name)->data; int i; - len = XSTRING (Vx_resource_name)->size; + len = STRING_BYTES (XSTRING (Vx_resource_name)); /* Only letters, digits, - and _ are valid in resource names. Count the valid characters and count the invalid ones. */ @@ -2077,22 +2190,22 @@ and the class is `Emacs.CLASS.SUBCLASS'.") /* Allocate space for the components, the dots which separate them, and the final '\0'. Make them big enough for the worst case. */ - name_key = (char *) alloca (XSTRING (Vx_resource_name)->size + name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name)) + (STRINGP (component) - ? XSTRING (component)->size : 0) - + XSTRING (attribute)->size + ? STRING_BYTES (XSTRING (component)) : 0) + + STRING_BYTES (XSTRING (attribute)) + 3); - class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) - + XSTRING (class)->size + class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class)) + + STRING_BYTES (XSTRING (class)) + (STRINGP (subclass) - ? XSTRING (subclass)->size : 0) + ? STRING_BYTES (XSTRING (subclass)) : 0) + 3); /* Start with emacs.FRAMENAME for the name (the specific one) and with `Emacs' for the class key (the general one). */ strcpy (name_key, XSTRING (Vx_resource_name)->data); - strcpy (class_key, EMACS_CLASS); + strcpy (class_key, XSTRING (Vx_resource_class)->data); strcat (class_key, "."); strcat (class_key, XSTRING (class)->data); @@ -2118,6 +2231,73 @@ and the class is `Emacs.CLASS.SUBCLASS'.") return Qnil; } +/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */ + +static Lisp_Object +display_x_get_resource (dpyinfo, attribute, class, component, subclass) + struct x_display_info *dpyinfo; + Lisp_Object attribute, class, component, subclass; +{ + register char *value; + char *name_key; + char *class_key; + + check_x (); + + CHECK_STRING (attribute, 0); + CHECK_STRING (class, 0); + + if (!NILP (component)) + CHECK_STRING (component, 1); + if (!NILP (subclass)) + CHECK_STRING (subclass, 2); + if (NILP (component) != NILP (subclass)) + error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither"); + + validate_x_resource_name (); + + /* Allocate space for the components, the dots which separate them, + and the final '\0'. Make them big enough for the worst case. */ + name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name)) + + (STRINGP (component) + ? STRING_BYTES (XSTRING (component)) : 0) + + STRING_BYTES (XSTRING (attribute)) + + 3); + + class_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_class)) + + STRING_BYTES (XSTRING (class)) + + (STRINGP (subclass) + ? STRING_BYTES (XSTRING (subclass)) : 0) + + 3); + + /* Start with emacs.FRAMENAME for the name (the specific one) + and with `Emacs' for the class key (the general one). */ + strcpy (name_key, XSTRING (Vx_resource_name)->data); + strcpy (class_key, XSTRING (Vx_resource_class)->data); + + strcat (class_key, "."); + strcat (class_key, XSTRING (class)->data); + + if (!NILP (component)) + { + strcat (class_key, "."); + strcat (class_key, XSTRING (subclass)->data); + + strcat (name_key, "."); + strcat (name_key, XSTRING (component)->data); + } + + strcat (name_key, "."); + strcat (name_key, XSTRING (attribute)->data); + + value = x_get_string_resource (dpyinfo->xrdb, name_key, class_key); + + if (value != (char *) 0) + return build_string (value); + else + return Qnil; +} + /* Used when C code wants a resource value. */ char * @@ -2130,7 +2310,7 @@ x_get_resource_string (attribute, class) /* Allocate space for the components, the dots which separate them, and the final '\0'. */ - name_key = (char *) alloca (XSTRING (Vinvocation_name)->size + name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name)) + strlen (attribute) + 2); class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); @@ -2162,7 +2342,8 @@ enum resource_types and don't let it get stored in any Lisp-visible variables! */ static Lisp_Object -x_get_arg (alist, param, attribute, class, type) +x_get_arg (dpyinfo, alist, param, attribute, class, type) + struct x_display_info *dpyinfo; Lisp_Object alist, param; char *attribute; char *class; @@ -2178,9 +2359,10 @@ x_get_arg (alist, param, attribute, class, type) if (attribute) { - tem = Fx_get_resource (build_string (attribute), - build_string (class), - Qnil, Qnil); + tem = display_x_get_resource (dpyinfo, + build_string (attribute), + build_string (class), + Qnil, Qnil); if (NILP (tem)) return Qunbound; @@ -2227,9 +2409,29 @@ x_get_arg (alist, param, attribute, class, type) return Fcdr (tem); } +/* Like x_get_arg, but also record the value in f->param_alist. */ + +static Lisp_Object +x_get_and_record_arg (f, alist, param, attribute, class, type) + struct frame *f; + Lisp_Object alist, param; + char *attribute; + char *class; + enum resource_types type; +{ + Lisp_Object value; + + value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param, + attribute, class, type); + if (! NILP (value)) + store_frame_param (f, param, value); + + return value; +} + /* Record in frame F the specified or default value according to ALIST - of the parameter named PARAM (a Lisp symbol). - If no value is specified for PARAM, look for an X default for XPROP + of the parameter named PROP (a Lisp symbol). + If no value is specified for PROP, look for an X default for XPROP on the frame named NAME. If that is not found either, use the value DEFLT. */ @@ -2245,7 +2447,7 @@ x_default_parameter (f, alist, prop, deflt, xprop, xclass, type) { Lisp_Object tem; - tem = x_get_arg (alist, prop, xprop, xclass, type); + tem = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, prop, xprop, xclass, type); if (EQ (tem, Qunbound)) tem = deflt; x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); @@ -2328,20 +2530,21 @@ x_figure_window_size (f, parms) int height, width, left, top; register int geometry; long window_prompting = 0; + struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); /* Default values if we fall through. Actually, if that happens we should get window manager prompting. */ - f->width = DEFAULT_COLS; + SET_FRAME_WIDTH (f, DEFAULT_COLS); f->height = DEFAULT_ROWS; /* Window managers expect that if program-specified positions are not (0,0), they're intentional, not defaults. */ 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); - tem2 = x_get_arg (parms, Quser_size, 0, 0, number); + tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, number); + tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, number); + tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, number); if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) { if (!EQ (tem0, Qunbound)) @@ -2352,7 +2555,7 @@ x_figure_window_size (f, parms) if (!EQ (tem1, Qunbound)) { CHECK_NUMBER (tem1, 0); - f->width = XINT (tem1); + SET_FRAME_WIDTH (f, XINT (tem1)); } if (!NILP (tem2) && !EQ (tem2, Qunbound)) window_prompting |= USSize; @@ -2369,9 +2572,9 @@ x_figure_window_size (f, parms) 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); - tem2 = x_get_arg (parms, Quser_position, 0, 0, number); + tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, number); + tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, number); + tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, number); if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) { if (EQ (tem0, Qminus)) @@ -2605,21 +2808,26 @@ x_window (f, window_prompting, minibuffer_only) : 0); extern char *lwlib_toolkit_type; +#if 0 /* Experimentally, we now get the right results + for -geometry -0-0 without this. 24 Aug 96, rms. */ if (FRAME_EXTERNAL_MENU_BAR (f)) { Dimension ibw = 0; XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL); menubar_size += ibw; } +#endif f->output_data.x->menubar_height = menubar_size; +#ifndef USE_LUCID /* 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); + XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth, + &extra_borders, NULL); + extra_borders *= 2; +#endif /* Convert our geometry parameters into a geometry string and specify it. @@ -2649,6 +2857,10 @@ x_window (f, window_prompting, minibuffer_only) } len = strlen (shell_position) + 1; + /* We don't free this because we don't know whether + it is safe to free it while the frame exists. + It isn't worth the trouble of arranging to free it + when the frame is deleted. */ tem = (char *) xmalloc (len); strncpy (tem, shell_position, len); XtSetArg (al[ac], XtNgeometry, tem); ac++; @@ -2663,7 +2875,7 @@ x_window (f, window_prompting, minibuffer_only) validate_x_resource_name (); class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data; - class_hints.res_class = EMACS_CLASS; + class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data; XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); #ifdef HAVE_X_I18N @@ -2756,6 +2968,7 @@ x_window (f, window_prompting, minibuffer_only) /* Create and set up the X window for frame F. */ +void x_window (f) struct frame *f; @@ -2823,7 +3036,7 @@ x_window (f) validate_x_resource_name (); class_hints.res_name = (char *) XSTRING (Vx_resource_name)->data; - class_hints.res_class = EMACS_CLASS; + class_hints.res_class = (char *) XSTRING (Vx_resource_class)->data; XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints); /* The menubar is part of the ordinary display; @@ -2839,6 +3052,7 @@ x_window (f) f->output_data.x->wm_hints.flags |= InputHint; XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &f->output_data.x->wm_hints); + f->output_data.x->wm_hints.icon_pixmap = None; /* Request "save yourself" and "delete window" commands from wm. */ { @@ -2883,11 +3097,12 @@ x_icon (f, parms) Lisp_Object parms; { Lisp_Object icon_x, icon_y; + struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); /* Set the position of the icon. Note that twm groups all icons in an icon window. */ - icon_x = x_get_arg (parms, Qicon_left, 0, 0, number); - icon_y = x_get_arg (parms, Qicon_top, 0, 0, number); + icon_x = x_get_and_record_arg (f, parms, Qicon_left, 0, 0, number); + icon_y = x_get_and_record_arg (f, parms, Qicon_top, 0, 0, number); if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound)) { CHECK_NUMBER (icon_x, 0); @@ -2903,7 +3118,7 @@ x_icon (f, parms) /* Start up iconic or window? */ x_wm_set_window_state - (f, (EQ (x_get_arg (parms, Qvisibility, 0, 0, symbol), Qicon) + (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, symbol), Qicon) ? IconicState : NormalState)); @@ -3009,7 +3224,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; @@ -3021,7 +3236,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, string); + display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, string); if (EQ (display, Qunbound)) display = Qnil; dpyinfo = check_x_display_info (display); @@ -3031,7 +3246,7 @@ This function is an internal primitive--use `make-frame' instead.") kb = &the_only_kboard; #endif - name = x_get_arg (parms, Qname, "name", "Name", string); + name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", string); if (!STRINGP (name) && ! EQ (name, Qunbound) && ! NILP (name)) @@ -3041,13 +3256,18 @@ This function is an internal primitive--use `make-frame' instead.") Vx_resource_name = name; /* See if parent window is specified. */ - parent = x_get_arg (parms, Qparent_id, NULL, NULL, number); + parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, number); if (EQ (parent, Qunbound)) parent = Qnil; if (! NILP (parent)) CHECK_NUMBER (parent, 0); - tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol); + /* 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 (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer", symbol); if (EQ (tem, Qnone) || NILP (tem)) f = make_frame_without_minibuffer (Qnil, kb, display); else if (EQ (tem, Qonly)) @@ -3060,19 +3280,19 @@ 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->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->output_data.x->fontset = -1; f->icon_name - = x_get_arg (parms, Qicon_name, "iconName", "Title", string); + = x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title", string); if (! STRINGP (f->icon_name)) f->icon_name = Qnil; @@ -3085,7 +3305,7 @@ This function is an internal primitive--use `make-frame' instead.") if (!NILP (parent)) { - f->output_data.x->parent_desc = parent; + f->output_data.x->parent_desc = (Window) XFASTINT (parent); f->output_data.x->explicit_parent = 1; } else @@ -3112,16 +3332,27 @@ This function is an internal primitive--use `make-frame' instead.") specbind (Qx_resource_name, name); } + /* Create fontsets from `global_fontset_alist' before handling fonts. */ + for (tem = Vglobal_fontset_alist; CONSP (tem); tem = XCONS (tem)->cdr) + fs_register_fontset (f, XCONS (tem)->car); + /* Extract the window parameters from the supplied values that are needed to determine window geometry. */ { Lisp_Object font; - font = x_get_arg (parms, Qfont, "font", "Font", string); + font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", string); + BLOCK_INPUT; /* First, try whatever font the caller has specified. */ if (STRINGP (font)) - font = x_new_font (f, XSTRING (font)->data); + { + tem = Fquery_fontset (font, Qnil); + if (STRINGP (tem)) + font = x_new_fontset (f, XSTRING (tem)->data); + else + font = x_new_font (f, XSTRING (font)->data); + } /* Try out a font which we hope has bold and italic variations. */ if (!STRINGP (font)) font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1"); @@ -3138,18 +3369,18 @@ This function is an internal primitive--use `make-frame' instead.") if (! STRINGP (font)) font = build_string ("fixed"); - x_default_parameter (f, parms, Qfont, font, + x_default_parameter (f, parms, Qfont, font, "font", "Font", string); } -#ifdef USE_X_TOOLKIT +#ifdef USE_LUCID /* Prevent lwlib/xlwmenu.c from crashing because of a bug whereby it fails to get any font. */ xlwmenu_default_font = f->output_data.x->font; #endif x_default_parameter (f, parms, Qborder_width, make_number (2), - "borderwidth", "BorderWidth", number); + "borderWidth", "BorderWidth", number); /* This defaults to 2 in order to match xterm. We recognize either internalBorderWidth or internalBorder (which is what xterm calls it). */ @@ -3157,16 +3388,16 @@ This function is an internal primitive--use `make-frame' instead.") { Lisp_Object value; - value = x_get_arg (parms, Qinternal_border_width, - "internalBorder", "BorderWidth", number); + value = x_get_arg (dpyinfo, parms, Qinternal_border_width, + "internalBorder", "internalBorder", number); if (! EQ (value, Qunbound)) parms = Fcons (Fcons (Qinternal_border_width, value), parms); } - x_default_parameter (f, parms, Qinternal_border_width, make_number (2), - "internalBorderWidth", "BorderWidth", number); - x_default_parameter (f, parms, Qvertical_scroll_bars, Qt, - "verticalScrollBars", "ScrollBars", boolean); + x_default_parameter (f, parms, Qinternal_border_width, make_number (1), + "internalBorderWidth", "internalBorderWidth", number); + x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft, + "verticalScrollBars", "ScrollBars", symbol); /* Also do the stuff which must be set before the window exists. */ x_default_parameter (f, parms, Qforeground_color, build_string ("black"), @@ -3235,7 +3466,8 @@ This function is an internal primitive--use `make-frame' instead.") f->height. */ width = f->width; height = f->height; - f->height = f->width = 0; + f->height = 0; + SET_FRAME_WIDTH (f, 0); change_frame_size (f, height, width, 1, 0); /* Tell the server what size and position, etc, we want, @@ -3244,7 +3476,7 @@ This function is an internal primitive--use `make-frame' instead.") x_wm_set_size_hint (f, window_prompting, 0); UNBLOCK_INPUT; - tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean); + tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, boolean); f->no_split = minibuffer_only || EQ (tem, Qt); UNGCPRO; @@ -3266,7 +3498,7 @@ This function is an internal primitive--use `make-frame' instead.") { Lisp_Object visibility; - visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol); + visibility = x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, symbol); if (EQ (visibility, Qunbound)) visibility = Qt; @@ -3285,6 +3517,7 @@ This function is an internal primitive--use `make-frame' instead.") /* FRAME is used only to get a handle on the X display. We don't pass the display info directly because we're called from frame.c, which doesn't know about that structure. */ + Lisp_Object x_get_focus_frame (frame) struct frame *frame; @@ -3297,23 +3530,11 @@ x_get_focus_frame (frame) XSETFRAME (xfocus, dpyinfo->x_focus_frame); return xfocus; } - -DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0, - "This function is obsolete, and does nothing.") - (frame) - Lisp_Object frame; -{ - return Qnil; -} - -DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0, - "This function is obsolete, and does nothing.") - () -{ - return Qnil; -} -DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0, +#if 1 +#include "x-list-font.c" +#else +DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 4, 0, "Return a list of the names of available fonts matching PATTERN.\n\ If optional arguments FACE and FRAME are specified, return only fonts\n\ the same size as FACE on FRAME.\n\ @@ -3328,9 +3549,12 @@ The return value is a list of strings, suitable as arguments to\n\ set-face-font.\n\ \n\ Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\ -even if they match PATTERN and FACE.") - (pattern, face, frame) - Lisp_Object pattern, face, frame; +even if they match PATTERN and FACE.\n\ +\n\ +The optional fourth argument MAXIMUM sets a limit on how many\n\ +fonts to match. The first MAXIMUM fonts are reported.") + (pattern, face, frame, maximum) + Lisp_Object pattern, face, frame, maximum; { int num_fonts; char **names; @@ -3340,12 +3564,23 @@ even if they match PATTERN and FACE.") XFontStruct *size_ref; Lisp_Object list; FRAME_PTR f; + Lisp_Object key; + int maxnames; + int count; check_x (); CHECK_STRING (pattern, 0); if (!NILP (face)) CHECK_SYMBOL (face, 1); + if (NILP (maximum)) + maxnames = 2000; + else + { + CHECK_NATNUM (maximum, 0); + maxnames = XINT (maximum); + } + f = check_x_frame (frame); /* Determine the width standard for comparison with the fonts we find. */ @@ -3374,7 +3609,8 @@ even if they match PATTERN and FACE.") } /* See if we cached the result for this particular query. */ - list = Fassoc (pattern, + key = Fcons (pattern, maximum); + list = Fassoc (key, XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr); /* We have info in the cache for this PATTERN. */ @@ -3396,13 +3632,13 @@ even if they match PATTERN and FACE.") { XFontStruct *thisinfo; - x_catch_errors (FRAME_X_DISPLAY (f)); + count = x_catch_errors (FRAME_X_DISPLAY (f)); thisinfo = XLoadQueryFont (FRAME_X_DISPLAY (f), XSTRING (XCONS (tem)->car)->data); x_check_errors (FRAME_X_DISPLAY (f), "XLoadQueryFont failure: %s"); - x_uncatch_errors (FRAME_X_DISPLAY (f)); + x_uncatch_errors (FRAME_X_DISPLAY (f), count); if (thisinfo && same_size_fonts (thisinfo, size_ref)) newlist = Fcons (XCONS (tem)->car, newlist); @@ -3418,25 +3654,25 @@ even if they match PATTERN and FACE.") BLOCK_INPUT; - x_catch_errors (FRAME_X_DISPLAY (f)); + count = x_catch_errors (FRAME_X_DISPLAY (f)); /* Solaris 2.3 has a bug in XListFontsWithInfo. */ #ifndef BROKEN_XLISTFONTSWITHINFO if (size_ref) names = XListFontsWithInfo (FRAME_X_DISPLAY (f), XSTRING (pattern)->data, - 2000, /* maxnames */ + maxnames, &num_fonts, /* count_return */ &info); /* info_return */ else #endif names = XListFonts (FRAME_X_DISPLAY (f), XSTRING (pattern)->data, - 2000, /* maxnames */ + maxnames, &num_fonts); /* count_return */ x_check_errors (FRAME_X_DISPLAY (f), "XListFonts failure: %s"); - x_uncatch_errors (FRAME_X_DISPLAY (f)); + x_uncatch_errors (FRAME_X_DISPLAY (f), count); UNBLOCK_INPUT; @@ -3453,7 +3689,7 @@ even if they match PATTERN and FACE.") for (i = 0; i < num_fonts; i++) full_list = Fcons (build_string (names[i]), full_list); XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr - = Fcons (Fcons (pattern, full_list), + = Fcons (Fcons (key, full_list), XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr); /* Make a list of the fonts that have the right width. */ @@ -3471,11 +3707,11 @@ even if they match PATTERN and FACE.") BLOCK_INPUT; - x_catch_errors (FRAME_X_DISPLAY (f)); + count = 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)); + x_uncatch_errors (FRAME_X_DISPLAY (f), count); UNBLOCK_INPUT; @@ -3507,6 +3743,7 @@ even if they match PATTERN and FACE.") return list; } +#endif DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 2, 0, @@ -3854,10 +4091,10 @@ x_char_height (f) } int -x_screen_planes (frame) - Lisp_Object frame; +x_screen_planes (f) + register struct frame *f; { - return FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes; + return FRAME_X_DISPLAY_INFO (f)->n_planes; } #if 0 /* These no longer seem like the right way to do things. */ @@ -4344,7 +4581,7 @@ DEFUN ("x-horizontal-line", Fx_horizontal_line, Sx_horizontal_line, 1, 1, "e", 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 + + (WINDOW_LEFT_MARGIN (w) * FONT_WIDTH (f->output_data.x->font)); register int right = left + (w->width * FONT_WIDTH (f->output_data.x->font)) @@ -4537,7 +4774,7 @@ DEFUN ("x-track-pointer", Fx_track_pointer, Sx_track_pointer, 1, 1, "e", if (tab_width <= 0 || tab_width > 20) tab_width = 8; do { - c = FETCH_CHAR (p); + c = FETCH_BYTE (p); if (len == f->width && hp == len - 1 && c != '\n') goto draw_or_not; @@ -4691,7 +4928,8 @@ also be depressed for NEWSTRING to appear.") if (NILP (modifiers)) XRebindKeysym (x_current_display, keysym, modifier_list, 0, - XSTRING (newstring)->data, XSTRING (newstring)->size); + XSTRING (newstring)->data, + STRING_BYTES (XSTRING (newstring))); else { register Lisp_Object rest, mod; @@ -4719,7 +4957,8 @@ also be depressed for NEWSTRING to appear.") } XRebindKeysym (x_current_display, keysym, modifier_list, i, - XSTRING (newstring)->data, XSTRING (newstring)->size); + XSTRING (newstring)->data, + STRING_BYTES (XSTRING (newstring))); } return Qnil; @@ -4750,7 +4989,7 @@ See the documentation of `x-rebind-key' for more information.") if (!NILP (item)) { CHECK_STRING (item, 2); - strsize = XSTRING (item)->size; + strsize = STRING_BYTES (XSTRING (item)); rawstring = (unsigned char *) xmalloc (strsize); bcopy (XSTRING (item)->data, rawstring, strsize); modifier[1] = 1 << i; @@ -4894,9 +5133,6 @@ terminate Emacs if we can't open the connection.") else xrm_option = (unsigned char *) 0; - /* Use this general default value to start with. */ - Vx_resource_name = Vinvocation_name; - validate_x_resource_name (); /* This is what opens the connection and sets x_current_display. @@ -5005,6 +5241,7 @@ x_sync (f) UNBLOCK_INPUT; } +void syms_of_xfns () { /* This is zero if not using X windows. */ @@ -5031,8 +5268,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"); @@ -5049,6 +5284,8 @@ syms_of_xfns () staticpro (&Qinternal_border_width); Qleft = intern ("left"); staticpro (&Qleft); + Qright = intern ("right"); + staticpro (&Qright); Qmouse_color = intern ("mouse-color"); staticpro (&Qmouse_color); Qnone = intern ("none"); @@ -5069,6 +5306,8 @@ syms_of_xfns () staticpro (&Qvisibility); Qwindow_id = intern ("window-id"); staticpro (&Qwindow_id); + Qouter_window_id = intern ("outer-window-id"); + staticpro (&Qouter_window_id); Qx_frame_parameter = intern ("x-frame-parameter"); staticpro (&Qx_frame_parameter); Qx_resource_name = intern ("x-resource-name"); @@ -5081,6 +5320,9 @@ syms_of_xfns () staticpro (&Qdisplay); /* This is the end of symbol initialization. */ + Qface_set_after_frame_default = intern ("face-set-after-frame-default"); + staticpro (&Qface_set_after_frame_default); + Fput (Qundefined_color, Qerror_conditions, Fcons (Qundefined_color, Fcons (Qerror, Qnil))); Fput (Qundefined_color, Qerror_message, @@ -5099,16 +5341,30 @@ unless you set the mouse color."); Vx_pointer_shape = Qnil; DEFVAR_LISP ("x-resource-name", &Vx_resource_name, - "The name Emacs uses to look up X resources; for internal use only.\n\ + "The name Emacs uses to look up X resources.\n\ `x-get-resource' uses this as the first component of the instance name\n\ when requesting resource values.\n\ Emacs initially sets `x-resource-name' to the name under which Emacs\n\ was invoked, or to the value specified with the `-name' or `-rn'\n\ -switches, if present."); +switches, if present.\n\ +\n\ +It may be useful to bind this variable locally around a call\n\ +to `x-get-resource'. See also the variable `x-resource-class'."); Vx_resource_name = Qnil; + DEFVAR_LISP ("x-resource-class", &Vx_resource_class, + "The class Emacs uses to look up X resources.\n\ +`x-get-resource' uses this as the first component of the instance class\n\ +when requesting resource values.\n\ +Emacs initially sets `x-resource-class' to \"Emacs\".\n\ +\n\ +Setting this variable permanently is not a reasonable thing to do,\n\ +but binding this variable locally around a call to `x-get-resource'\n\ +is a reasonabvle practice. See also the variable `x-resource-name'."); + Vx_resource_class = build_string (EMACS_CLASS); + #if 0 /* This doesn't really do anything. */ - DEFVAR_INT ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape, + DEFVAR_LISP ("x-nontext-pointer-shape", &Vx_nontext_pointer_shape, "The shape of the pointer when not over text.\n\ This variable takes effect when you create a new frame\n\ or when you set the mouse color."); @@ -5116,14 +5372,14 @@ or when you set the mouse color."); Vx_nontext_pointer_shape = Qnil; #if 0 /* This doesn't really do anything. */ - DEFVAR_INT ("x-mode-pointer-shape", &Vx_mode_pointer_shape, + DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape, "The shape of the pointer when over the mode line.\n\ This variable takes effect when you create a new frame\n\ or when you set the mouse color."); #endif Vx_mode_pointer_shape = Qnil; - DEFVAR_INT ("x-sensitive-text-pointer-shape", + DEFVAR_LISP ("x-sensitive-text-pointer-shape", &Vx_sensitive_text_pointer_shape, "The shape of the pointer when over mouse-sensitive text.\n\ This variable takes effect when you create a new frame\n\ @@ -5142,6 +5398,25 @@ unless you set it to something else."); and maybe the user would like to set it to t. */ Vx_no_window_manager = Qnil; + DEFVAR_LISP ("x-pixel-size-width-font-regexp", + &Vx_pixel_size_width_font_regexp, + "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\ +\n\ +Since Emacs gets width of a font matching with this regexp from\n\ +PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\ +such a font. This is especially effective for such large fonts as\n\ +Chinese, Japanese, and Korean."); + Vx_pixel_size_width_font_regexp = Qnil; + + DEFVAR_BOOL ("unibyte-display-via-language-environment", + &unibyte_display_via_language_environment, + "*Non-nil means display unibyte text according to language environment.\n\ +Specifically this means that unibyte non-ASCII characters\n\ +are displayed by converting them to the equivalent multibyte characters\n\ +according to the current language environment. As a result, they are\n\ +displayed according to the current fontset."); + unibyte_display_via_language_environment = 0; + #ifdef USE_X_TOOLKIT Fprovide (intern ("x-toolkit")); #endif @@ -5183,8 +5458,6 @@ unless you set it to something else."); #endif defsubr (&Sx_parse_geometry); defsubr (&Sx_create_frame); - defsubr (&Sfocus_frame); - defsubr (&Sunfocus_frame); #if 0 defsubr (&Sx_horizontal_line); #endif @@ -5192,6 +5465,15 @@ unless you set it to something else."); defsubr (&Sx_close_connection); defsubr (&Sx_display_list); defsubr (&Sx_synchronize); + + /* Setting callback functions for fontset handler. */ + get_font_info_func = x_get_font_info; + list_fonts_func = x_list_fonts; + load_font_func = x_load_font; + find_ccl_program_func = x_find_ccl_program; + query_font_func = x_query_font; + set_frame_fontset_func = x_set_font; + check_window_system_func = check_x; } #endif /* HAVE_X_WINDOWS */