X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/29fabd8cee50416f35fee189822f48b9d9ea19de..fbf349734468d48b421c3d03074bb66dfcf3115b:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index de95a59112..11f4c2eadb 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1,6 +1,6 @@ /* Functions for the X window system. - Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000,01,02,03,04 - Free Software Foundation. + Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -16,11 +16,10 @@ 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, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #include -#include #include #include @@ -48,6 +47,7 @@ Boston, MA 02111-1307, USA. */ #include "systime.h" #include "termhooks.h" #include "atimer.h" +#include "termchar.h" #ifdef HAVE_X_WINDOWS @@ -151,6 +151,10 @@ char *gray_bitmap_bits = gray_bits; int display_hourglass_p; +/* Non-zero means prompt with the old GTK file selection dialog. */ + +int x_use_old_gtk_file_dialog; + /* The background and shape of the mouse pointer, and shape when not over text or in the modeline. */ @@ -235,17 +239,18 @@ check_x_frame (frame) return f; } -/* Let the user specify an X display with a frame. +/* Let the user specify an X display with a Lisp object. + OBJECT may be nil, a frame or a device id. nil stands for the selected frame--or, if that is not an X frame, the first X display on the list. */ struct x_display_info * -check_x_display_info (frame) - Lisp_Object frame; +check_x_display_info (object) + Lisp_Object object; { struct x_display_info *dpyinfo = NULL; - if (NILP (frame)) + if (NILP (object)) { struct frame *sf = XFRAME (selected_frame); @@ -256,11 +261,20 @@ check_x_display_info (frame) else error ("X windows are not in use or not initialized"); } - else if (STRINGP (frame)) - dpyinfo = x_display_info_for_name (frame); + else if (INTEGERP (object)) + { + struct device *d = get_device (XINT (object), 1); + + if (d->type != output_x_window) + error ("Display %d is not an X display", XINT (object)); + + dpyinfo = d->display_info.x; + } + else if (STRINGP (object)) + dpyinfo = x_display_info_for_name (object); else { - FRAME_PTR f = check_x_frame (frame); + FRAME_PTR f = check_x_frame (object); dpyinfo = FRAME_X_DISPLAY_INFO (f); } @@ -1379,10 +1393,8 @@ x_set_tool_bar_lines (f, value, oldval) below the menu bar. */ if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0) { - updating_frame = f; - clear_frame (); + clear_frame (f); clear_current_matrices (f); - updating_frame = NULL; } /* If the tool bar gets smaller, the internal border below it @@ -1394,10 +1406,14 @@ x_set_tool_bar_lines (f, value, oldval) int width = FRAME_PIXEL_WIDTH (f); int y = nlines * FRAME_LINE_HEIGHT (f); - BLOCK_INPUT; - x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - 0, y, width, height, False); - UNBLOCK_INPUT; + /* height can be zero here. */ + if (height > 0 && width > 0) + { + BLOCK_INPUT; + x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + 0, y, width, height, False); + UNBLOCK_INPUT; + } if (WINDOWP (f->tool_bar_window)) clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); @@ -1429,10 +1445,10 @@ x_set_scroll_bar_foreground (f, value, oldval) if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) { /* Remove all scroll bars because they have wrong colors. */ - if (condemn_scroll_bars_hook) - (*condemn_scroll_bars_hook) (f); - if (judge_scroll_bars_hook) - (*judge_scroll_bars_hook) (f); + if (FRAME_DEVICE (f)->condemn_scroll_bars_hook) + (*FRAME_DEVICE (f)->condemn_scroll_bars_hook) (f); + if (FRAME_DEVICE (f)->judge_scroll_bars_hook) + (*FRAME_DEVICE (f)->judge_scroll_bars_hook) (f); update_face_from_frame_parameter (f, Qscroll_bar_foreground, value); redraw_frame (f); @@ -1478,10 +1494,10 @@ x_set_scroll_bar_background (f, value, oldval) if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) { /* Remove all scroll bars because they have wrong colors. */ - if (condemn_scroll_bars_hook) - (*condemn_scroll_bars_hook) (f); - if (judge_scroll_bars_hook) - (*judge_scroll_bars_hook) (f); + if (FRAME_DEVICE (f)->condemn_scroll_bars_hook) + (*FRAME_DEVICE (f)->condemn_scroll_bars_hook) (f); + if (FRAME_DEVICE (f)->judge_scroll_bars_hook) + (*FRAME_DEVICE (f)->judge_scroll_bars_hook) (f); update_face_from_frame_parameter (f, Qscroll_bar_background, value); redraw_frame (f); @@ -1872,7 +1888,8 @@ hack_wm_protocols (f, widget) BLOCK_INPUT; { - Atom type, *atoms = 0; + Atom type; + unsigned char *catoms; int format = 0; unsigned long nitems = 0; unsigned long bytes_after; @@ -1881,20 +1898,27 @@ hack_wm_protocols (f, widget) FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, (long)0, (long)100, False, XA_ATOM, &type, &format, &nitems, &bytes_after, - (unsigned char **) &atoms) + &catoms) == Success) && format == 32 && type == XA_ATOM) - while (nitems > 0) - { - nitems--; - if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window) - need_delete = 0; - else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus) - need_focus = 0; - else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself) - need_save = 0; - } - if (atoms) XFree ((char *) atoms); + { + Atom *atoms = (Atom *) catoms; + while (nitems > 0) + { + nitems--; + if (atoms[nitems] + == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window) + need_delete = 0; + else if (atoms[nitems] + == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus) + need_focus = 0; + else if (atoms[nitems] + == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself) + need_save = 0; + } + } + if (catoms) + XFree (catoms); } { Atom props [10]; @@ -1941,29 +1965,200 @@ static XIMStyle supported_xim_styles[] = }; -/* Create an X fontset on frame F with base font name - BASE_FONTNAME.. */ +/* Create an X fontset on frame F with base font name BASE_FONTNAME. */ + +char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*"; + +/* Create an Xt fontset spec from the name of a base font. + If `motif' is True use the Motif syntax. */ +char * +xic_create_fontsetname (base_fontname, motif) + char *base_fontname; + Bool motif; +{ + const char *sep = motif ? ";" : ","; + char *fontsetname; + + /* Make a fontset name from the base font name. */ + if (xic_defaut_fontset == base_fontname) + { /* There is no base font name, use the default. */ + int len = strlen (base_fontname) + 2; + fontsetname = xmalloc (len); + bzero (fontsetname, len); + strcpy (fontsetname, base_fontname); + } + else + { + /* Make a fontset name from the base font name. + The font set will be made of the following elements: + - the base font. + - the base font where the charset spec is replaced by -*-*. + - the same but with the family also replaced with -*-*-. */ + char *p = base_fontname; + int i; + + for (i = 0; *p; p++) + if (*p == '-') i++; + if (i != 14) + { /* As the font name doesn't conform to XLFD, we can't + modify it to generalize it to allcs and allfamilies. + Use the specified font plus the default. */ + int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3; + fontsetname = xmalloc (len); + bzero (fontsetname, len); + strcpy (fontsetname, base_fontname); + strcat (fontsetname, sep); + strcat (fontsetname, xic_defaut_fontset); + } + else + { + int len; + char *p1 = NULL, *p2 = NULL; + char *font_allcs = NULL; + char *font_allfamilies = NULL; + char *font_all = NULL; + char *allcs = "*-*-*-*-*-*-*"; + char *allfamilies = "-*-*-"; + char *all = "*-*-*-*-"; + + for (i = 0, p = base_fontname; i < 8; p++) + { + if (*p == '-') + { + i++; + if (i == 3) + p1 = p + 1; + else if (i == 7) + p2 = p + 1; + } + } + /* Build the font spec that matches all charsets. */ + len = p - base_fontname + strlen (allcs) + 1; + font_allcs = (char *) alloca (len); + bzero (font_allcs, len); + bcopy (base_fontname, font_allcs, p - base_fontname); + strcat (font_allcs, allcs); + + /* Build the font spec that matches all families. */ + len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1; + font_allfamilies = (char *) alloca (len); + bzero (font_allfamilies, len); + strcpy (font_allfamilies, allfamilies); + bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1); + strcat (font_allfamilies, allcs); + + /* Build the font spec that matches all. */ + len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1; + font_all = (char *) alloca (len); + bzero (font_all, len); + strcpy (font_all, allfamilies); + strcat (font_all, all); + bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2); + strcat (font_all, allcs); + + /* Build the actual font set name. */ + len = strlen (base_fontname) + strlen (font_allcs) + + strlen (font_allfamilies) + strlen (font_all) + 5; + fontsetname = xmalloc (len); + bzero (fontsetname, len); + strcpy (fontsetname, base_fontname); + strcat (fontsetname, sep); + strcat (fontsetname, font_allcs); + strcat (fontsetname, sep); + strcat (fontsetname, font_allfamilies); + strcat (fontsetname, sep); + strcat (fontsetname, font_all); + } + } + if (motif) + strcat (fontsetname, ":"); + return fontsetname; +} static XFontSet xic_create_xfontset (f, base_fontname) struct frame *f; char *base_fontname; { - XFontSet xfs; - char **missing_list; + XFontSet xfs = NULL; + char **missing_list = NULL; int missing_count; char *def_string; + Lisp_Object rest, frame; + + if (!base_fontname) + base_fontname = xic_defaut_fontset; + + /* See if there is another frame already using same fontset. */ + FOR_EACH_FRAME (rest, frame) + { + struct frame *cf = XFRAME (frame); + if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf) + && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f) + && FRAME_XIC_BASE_FONTNAME (cf) + && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname)) + { + xfs = FRAME_XIC_FONTSET (cf); + break; + } + } + + if (!xfs) + { + char *fontsetname = xic_create_fontsetname (base_fontname, False); + + /* New fontset. */ + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), + fontsetname, &missing_list, + &missing_count, &def_string); + if (missing_list) + XFreeStringList (missing_list); + xfree (fontsetname); + } - xfs = XCreateFontSet (FRAME_X_DISPLAY (f), - base_fontname, &missing_list, - &missing_count, &def_string); - if (missing_list) - XFreeStringList (missing_list); + if (FRAME_XIC_BASE_FONTNAME (f)) + xfree (FRAME_XIC_BASE_FONTNAME (f)); + FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname); - /* No need to free def_string. */ + /* No need to free def_string. */ return xfs; } +/* Free the X fontset of frame F if it is the last frame using it. */ + +void +xic_free_xfontset (f) + struct frame *f; +{ + Lisp_Object rest, frame; + int shared_p = 0; + + if (!FRAME_XIC_FONTSET (f)) + return; + + /* See if there is another frame sharing the same fontset. */ + FOR_EACH_FRAME (rest, frame) + { + struct frame *cf = XFRAME (frame); + if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf) + && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f) + && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f)) + { + shared_p = 1; + break; + } + } + + if (!shared_p) + /* The fontset is not used anymore. It is safe to free it. */ + XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); + + if (FRAME_XIC_BASE_FONTNAME (f)) + xfree (FRAME_XIC_BASE_FONTNAME (f)); + FRAME_XIC_BASE_FONTNAME (f) = NULL; + FRAME_XIC_FONTSET (f) = NULL; +} + /* Value is the best input style, given user preferences USER (already checked to be supported by Emacs), and styles supported by the @@ -2000,6 +2195,11 @@ create_frame_xic (f) if (FRAME_XIC (f)) return; + /* Create X fontset. */ + xfs = xic_create_xfontset + (f, (FRAME_FONTSET (f) < 0) ? NULL + : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f)))); + xim = FRAME_X_XIM (f); if (xim) { @@ -2007,52 +2207,9 @@ create_frame_xic (f) XPoint spot; XVaNestedList preedit_attr; XVaNestedList status_attr; - char *base_fontname; - int fontset; s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1; spot.x = 0; spot.y = 1; - /* Create X fontset. */ - fontset = FRAME_FONTSET (f); - if (fontset < 0) - base_fontname = "-*-*-*-r-normal--14-*-*-*-*-*-*-*"; - else - { - /* Determine the base fontname from the ASCII font name of - FONTSET. */ - char *ascii_font = (char *) SDATA (fontset_ascii (fontset)); - char *p = ascii_font; - int i; - - for (i = 0; *p; p++) - if (*p == '-') i++; - if (i != 14) - /* As the font name doesn't conform to XLFD, we can't - modify it to get a suitable base fontname for the - frame. */ - base_fontname = "-*-*-*-r-normal--14-*-*-*-*-*-*-*"; - else - { - int len = strlen (ascii_font) + 1; - char *p1 = NULL; - - for (i = 0, p = ascii_font; i < 8; p++) - { - if (*p == '-') - { - i++; - if (i == 3) - p1 = p + 1; - } - } - base_fontname = (char *) alloca (len); - bzero (base_fontname, len); - strcpy (base_fontname, "-*-*-"); - bcopy (p1, base_fontname + 5, p - p1); - strcat (base_fontname, "*-*-*-*-*-*-*"); - } - } - xfs = xic_create_xfontset (f, base_fontname); /* Determine XIC style. */ if (xic_style == 0) @@ -2114,11 +2271,9 @@ free_frame_xic (f) return; XDestroyIC (FRAME_XIC (f)); - if (FRAME_XIC_FONTSET (f)) - XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); + xic_free_xfontset (f); FRAME_XIC (f) = NULL; - FRAME_XIC_FONTSET (f) = NULL; } @@ -2197,6 +2352,8 @@ xic_set_xfontset (f, base_fontname) XVaNestedList attr; XFontSet xfs; + xic_free_xfontset (f); + xfs = xic_create_xfontset (f, base_fontname); attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL); @@ -2206,8 +2363,6 @@ xic_set_xfontset (f, base_fontname) XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL); XFree (attr); - if (FRAME_XIC_FONTSET (f)) - XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); FRAME_XIC_FONTSET (f) = xfs; } @@ -2795,6 +2950,12 @@ unwind_create_frame (frame) { struct frame *f = XFRAME (frame); + /* If frame is already dead, nothing to do. This can happen if the + display is disconnected after the frame has become official, but + before x_create_frame removes the unwind protect. */ + if (!FRAME_LIVE_P (f)) + return Qnil; + /* If frame is ``official'', nothing to do. */ if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame)) { @@ -2804,9 +2965,11 @@ unwind_create_frame (frame) x_free_frame_resources (f); +#if GLYPH_DEBUG /* Check that reference counts are indeed correct. */ xassert (dpyinfo->reference_count == dpyinfo_refcount); xassert (dpyinfo->image_cache->refcount == image_cache_refcount); +#endif return Qt; } @@ -2841,18 +3004,18 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object parent; struct kboard *kb; - check_x (); - /* Use this general default value to start with until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; - display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING); + display = x_get_arg (dpyinfo, parms, Qdevice, 0, 0, RES_TYPE_NUMBER); + if (EQ (display, Qunbound)) + display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING); if (EQ (display, Qunbound)) display = Qnil; dpyinfo = check_x_display_info (display); #ifdef MULTI_KBOARD - kb = dpyinfo->kboard; + kb = dpyinfo->device->kboard; #else kb = &the_only_kboard; #endif @@ -2897,6 +3060,9 @@ This function is an internal primitive--use `make-frame' instead. */) /* Note that X Windows does support scroll bars. */ FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; + f->device = dpyinfo->device; + f->device->reference_count++; + 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)); @@ -2921,9 +3087,6 @@ This function is an internal primitive--use `make-frame' instead. */) image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ -#ifdef MULTI_KBOARD - FRAME_KBOARD (f) = kb; -#endif /* These colors will be set anyway later, but it's important to get the color reference counts right, so initialize them! */ @@ -2986,6 +3149,8 @@ This function is an internal primitive--use `make-frame' instead. */) specbind (Qx_resource_name, name); } + Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qx), Qnil)); + /* Extract the window parameters from the supplied values that are needed to determine window geometry. */ { @@ -3311,10 +3476,10 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, doc: /* Internal function called by `display-color-p', which see. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); if (dpyinfo->n_planes <= 2) return Qnil; @@ -3336,13 +3501,13 @@ DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0, doc: /* Return t if the X display supports shades of gray. Note that color displays do support shades of gray. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). -If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). +If omitted or nil, that stands for the selected frame's display device. */) + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); if (dpyinfo->n_planes <= 1) return Qnil; @@ -3364,56 +3529,56 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0, - doc: /* Returns the width in pixels of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the width in pixels of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (dpyinfo->width); } DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0, - doc: /* Returns the height in pixels of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the height in pixels of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (dpyinfo->height); } DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0, - doc: /* Returns the number of bitplanes of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the number of bitplanes of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (dpyinfo->n_planes); } DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0, - doc: /* Returns the number of color cells of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the number of color cells of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); int nr_planes = DisplayPlanes (dpyinfo->display, XScreenNumberOfScreen (dpyinfo->screen)); @@ -3431,27 +3596,29 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-server-max-request-size", Fx_server_max_request_size, Sx_server_max_request_size, 0, 1, 0, - doc: /* Returns the maximum request size of the X server of display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the maximum request size of the X server of display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (MAXREQUEST (dpyinfo->display)); } DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0, - doc: /* Returns the vendor ID string of the X server of display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns the "vendor ID" string of the X server of display DEVICE. +\(Labelling every distributor as a "vendor" embodies the false assumption +that operating systems cannot be developed and distributed noncommercially.) +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); char *vendor = ServerVendor (dpyinfo->display); if (! vendor) vendor = ""; @@ -3459,18 +3626,18 @@ If omitted or nil, that stands for the selected frame's display. */) } DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0, - doc: /* Returns the version numbers of the X server of display DISPLAY. + doc: /* Returns the version numbers of the X server of display DEVICE. The value is a list of three integers: the major and minor -version numbers of the X Protocol in use, and the vendor-specific release +version numbers of the X Protocol in use, and the distributor-specific release number. See also the function `x-server-vendor'. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); Display *dpy = dpyinfo->display; return Fcons (make_number (ProtocolVersion (dpy)), @@ -3479,55 +3646,55 @@ If omitted or nil, that stands for the selected frame's display. */) } DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, - doc: /* Return the number of screens on the X server of display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Return the number of screens on the X server of display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (ScreenCount (dpyinfo->display)); } DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0, - doc: /* Return the height in millimeters of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Return the height in millimeters of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (HeightMMOfScreen (dpyinfo->screen)); } DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, - doc: /* Return the width in millimeters of the X display DISPLAY. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Return the width in millimeters of the X display DEVICE. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); return make_number (WidthMMOfScreen (dpyinfo->screen)); } DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store, 0, 1, 0, - doc: /* Returns an indication of whether X display DISPLAY does backing store. + doc: /* Returns an indication of whether X display DEVICE does backing store. The value may be `always', `when-mapped', or `not-useful'. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); Lisp_Object result; switch (DoesBackingStore (dpyinfo->screen)) @@ -3554,17 +3721,17 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-visual-class", Fx_display_visual_class, Sx_display_visual_class, 0, 1, 0, - doc: /* Return the visual class of the X display DISPLAY. + doc: /* Return the visual class of the X display DEVICE. The value is one of the symbols `static-gray', `gray-scale', `static-color', `pseudo-color', `true-color', or `direct-color'. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). +The optional argument DEVICE specifies which display to ask about. +DEVICE should a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); Lisp_Object result; switch (dpyinfo->visual->class) @@ -3597,14 +3764,14 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0, - doc: /* Returns t if the X display DISPLAY supports the save-under feature. -The optional argument DISPLAY specifies which display to ask about. -DISPLAY should be either a frame or a display name (a string). + doc: /* Returns t if the X display DEVICE supports the save-under feature. +The optional argument DEVICE specifies which display to ask about. +DEVICE should be a device id, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) - (display) - Lisp_Object display; + (device) + Lisp_Object device; { - struct x_display_info *dpyinfo = check_x_display_info (display); + struct x_display_info *dpyinfo = check_x_display_info (device); if (DoesSaveUnders (dpyinfo->screen) == True) return Qt; @@ -3785,8 +3952,10 @@ x_display_info_for_name (name) CHECK_STRING (name); - if (! EQ (Vwindow_system, intern ("x"))) - error ("Not using X Windows"); +#if 0 + if (! EQ (Vinitial_window_system, intern ("x"))) + error ("Not using X Windows"); /* That doesn't stop us anymore. */ +#endif for (dpyinfo = x_display_list, names = x_display_name_list; dpyinfo; @@ -3833,8 +4002,10 @@ terminate Emacs if we can't open the connection. */) if (! NILP (xrm_string)) CHECK_STRING (xrm_string); - if (! EQ (Vwindow_system, intern ("x"))) - error ("Not using X Windows"); +#if 0 + if (! EQ (Vinitial_window_system, intern ("x"))) + error ("Not using X Windows"); /* That doesn't stop us anymore. */ +#endif if (! NILP (xrm_string)) xrm_option = (unsigned char *) SDATA (xrm_string); @@ -3876,30 +4047,11 @@ If DISPLAY is nil, that stands for the selected frame's display. */) Lisp_Object display; { struct x_display_info *dpyinfo = check_x_display_info (display); - int i; if (dpyinfo->reference_count > 0) error ("Display still has frames on it"); - BLOCK_INPUT; - /* Free the fonts in the font table. */ - for (i = 0; i < dpyinfo->n_fonts; i++) - if (dpyinfo->font_table[i].name) - { - XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font); - } - - x_destroy_all_bitmaps (dpyinfo); - XSetCloseDownMode (dpyinfo->display, DestroyAll); - -#ifdef USE_X_TOOLKIT - XtCloseDisplay (dpyinfo->display); -#else - XCloseDisplay (dpyinfo->display); -#endif - - x_delete_display (dpyinfo); - UNBLOCK_INPUT; + x_delete_device (dpyinfo->device); return Qnil; } @@ -4004,8 +4156,13 @@ Value is VALUE. */) data = (unsigned char *) xmalloc (nelements); else if (element_format == 16) data = (unsigned char *) xmalloc (nelements*2); - else - data = (unsigned char *) xmalloc (nelements*4); + else /* format == 32 */ + /* The man page for XChangeProperty: + "If the specified format is 32, the property data must be a + long array." + This applies even if long is more than 64 bits. The X library + converts to 32 bits before sending to the X server. */ + data = (unsigned char *) xmalloc (nelements * sizeof(long)); x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); } @@ -4026,7 +4183,7 @@ Value is VALUE. */) if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f); else w = FRAME_X_WINDOW (f); - + XChangeProperty (FRAME_X_DISPLAY (f), w, prop_atom, target_type, element_format, PropModeReplace, data, nelements); @@ -4084,7 +4241,7 @@ no value of TYPE. */) Atom prop_atom; int rc; Lisp_Object prop_value = Qnil; - char *tmp_data = NULL; + unsigned char *tmp_data = NULL; Atom actual_type; Atom target_type = XA_STRING; int actual_format; @@ -4124,7 +4281,7 @@ no value of TYPE. */) rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window, prop_atom, 0, 0, False, target_type, &actual_type, &actual_format, &actual_size, - &bytes_remaining, (unsigned char **) &tmp_data); + &bytes_remaining, &tmp_data); if (rc == Success) { int size = bytes_remaining; @@ -4137,14 +4294,38 @@ no value of TYPE. */) ! NILP (delete_p), target_type, &actual_type, &actual_format, &actual_size, &bytes_remaining, - (unsigned char **) &tmp_data); + &tmp_data); if (rc == Success && tmp_data) { + /* The man page for XGetWindowProperty says: + "If the returned format is 32, the returned data is represented + as a long array and should be cast to that type to obtain the + elements." + This applies even if long is more than 32 bits, the X library + converts from 32 bit elements received from the X server to long + and passes the long array to us. Thus, for that case bcopy can not + be used. We convert to a 32 bit type here, because so much code + assume on that. + + The bytes and offsets passed to XGetWindowProperty refers to the + property and those are indeed in 32 bit quantities if format is + 32. */ + + if (actual_format == 32 && actual_format < BITS_PER_LONG) + { + unsigned long i; + int *idata = (int *) tmp_data; + long *ldata = (long *) tmp_data; + + for (i = 0; i < actual_size; ++i) + idata[i] = (int) ldata[i]; + } + if (NILP (vector_ret_p)) prop_value = make_string (tmp_data, size); else prop_value = x_property_data_to_lisp (f, - (unsigned char *) tmp_data, + tmp_data, actual_type, actual_format, actual_size); @@ -4187,6 +4368,14 @@ static Lisp_Object Vhourglass_delay; static void show_hourglass P_ ((struct atimer *)); static void hide_hourglass P_ ((void)); +/* Return non-zero if houglass timer has been started or hourglass is shown. */ + +int +hourglass_started () +{ + return hourglass_shown_p || hourglass_atimer != NULL; +} + /* Cancel a currently active hourglass timer, and start a new one. */ @@ -4278,11 +4467,15 @@ show_hourglass (timer) { unsigned long mask = CWCursor; XSetWindowAttributes attrs; - +#ifdef USE_GTK + Window parent = FRAME_X_WINDOW (f); +#else + Window parent = FRAME_OUTER_WINDOW (f); +#endif attrs.cursor = f->output_data.x->hourglass_cursor; f->output_data.x->hourglass_window - = XCreateWindow (dpy, FRAME_OUTER_WINDOW (f), + = XCreateWindow (dpy, parent, 0, 0, 32000, 32000, 0, 0, InputOnly, CopyFromParent, @@ -4403,30 +4596,18 @@ x_create_tip_frame (dpyinfo, parms, text) int width, height; int count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3; - struct kboard *kb; int face_change_count_before = face_change_count; Lisp_Object buffer; struct buffer *old_buffer; check_x (); - /* Use this general default value to start with until we know if - this frame has a specified name. */ - Vx_resource_name = Vinvocation_name; - -#ifdef MULTI_KBOARD - kb = dpyinfo->kboard; -#else - kb = &the_only_kboard; -#endif - /* Get the name of the frame to use for resource lookup. */ name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING); if (!STRINGP (name) && !EQ (name, Qunbound) && !NILP (name)) error ("Invalid frame name--not a string or nil"); - Vx_resource_name = name; frame = Qnil; GCPRO3 (parms, name, frame); @@ -4447,6 +4628,9 @@ x_create_tip_frame (dpyinfo, parms, text) FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; record_unwind_protect (unwind_create_tip_frame, frame); + f->device = dpyinfo->device; + f->device->reference_count++; + /* By setting the output method, we're essentially saying that the frame is live, as per FRAME_LIVE_P. If we get a signal from this point on, x_destroy_window might screw up reference @@ -4468,9 +4652,6 @@ x_create_tip_frame (dpyinfo, parms, text) image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ -#ifdef MULTI_KBOARD - FRAME_KBOARD (f) = kb; -#endif f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; f->output_data.x->explicit_parent = 0; @@ -4480,6 +4661,16 @@ x_create_tip_frame (dpyinfo, parms, text) Lisp_Object black; struct gcpro gcpro1; + /* Function x_decode_color can signal an error. Make + sure to initialize color slots so that we won't try + to free colors we haven't allocated. */ + f->output_data.x->foreground_pixel = -1; + f->output_data.x->background_pixel = -1; + f->output_data.x->cursor_pixel = -1; + f->output_data.x->cursor_foreground_pixel = -1; + f->output_data.x->border_pixel = -1; + f->output_data.x->mouse_pixel = -1; + black = build_string ("black"); GCPRO1 (black); f->output_data.x->foreground_pixel @@ -4670,6 +4861,8 @@ x_create_tip_frame (dpyinfo, parms, text) Qnil)); } + Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qx), Qnil)); + f->no_split = 1; UNGCPRO; @@ -4895,7 +5088,7 @@ Text larger than the specified size is clipped. */) clear_glyph_matrix (w->desired_matrix); clear_glyph_matrix (w->current_matrix); SET_TEXT_POS (pos, BEGV, BEGV_BYTE); - try_window (FRAME_ROOT_WINDOW (f), pos); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ width = height = 0; @@ -5048,28 +5241,48 @@ file_dialog_unmap_cb (widget, client_data, call_data) *result = XmCR_CANCEL; } +static Lisp_Object +clean_up_file_dialog (arg) + Lisp_Object arg; +{ + struct Lisp_Save_Value *p = XSAVE_VALUE (arg); + Widget dialog = (Widget) p->pointer; -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, + /* Clean up. */ + BLOCK_INPUT; + XtUnmanageChild (dialog); + XtDestroyWidget (dialog); + x_menu_set_in_use (0); + UNBLOCK_INPUT; + + return Qnil; +} + + +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, doc: /* Read file name, prompting with PROMPT in directory DIR. -Use a file selection dialog. -Select DEFAULT-FILENAME in the dialog's file selection box, if -specified. Don't let the user enter a file name in the file -selection dialog's entry field, if MUSTMATCH is non-nil. */) - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file +selection box, if specified. If MUSTMATCH is non-nil, the returned file +or directory must exist. ONLY-DIR-P is ignored." */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { int result; struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; - Widget dialog, text, list, help; + Widget dialog, text, help; Arg al[10]; int ac = 0; extern XtAppContext Xt_app_con; XmString dir_xmstring, pattern_xmstring; int count = SPECPDL_INDEX (); - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; + + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); + + if (popup_activated ()) + error ("Trying to use a menu from within a menu-entry"); - GCPRO5 (prompt, dir, default_filename, mustmatch, file); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -5102,9 +5315,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb, (XtPointer) &result); - /* Disable the help button since we can't display help. */ + /* Remove the help button since we can't display help. */ help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); - XtSetSensitive (help, False); + XtUnmanageChild (help); /* Mark OK button as default. */ XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON), @@ -5126,39 +5339,53 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) /* Manage the dialog, so that list boxes get filled. */ XtManageChild (dialog); - /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME - must include the path for this to work. */ - list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST); if (STRINGP (default_filename)) { XmString default_xmstring; - int item_pos; + Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT); + Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST); - default_xmstring - = XmStringCreateLocalized (SDATA (default_filename)); + XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext); + XmTextFieldReplace (wtext, 0, last_pos, + (SDATA (Ffile_name_nondirectory (default_filename)))); - if (!XmListItemExists (list, default_xmstring)) - { - /* Add a new item if DEFAULT_FILENAME is not in the list. */ - XmListAddItem (list, default_xmstring, 0); - item_pos = 0; - } - else - item_pos = XmListItemPos (list, default_xmstring); - XmStringFree (default_xmstring); + /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME + must include the path for this to work. */ + + default_xmstring = XmStringCreateLocalized (SDATA (default_filename)); - /* Select the item and scroll it into view. */ - XmListSelectPos (list, item_pos, True); - XmListSetPos (list, item_pos); + if (XmListItemExists (list, default_xmstring)) + { + int item_pos = XmListItemPos (list, default_xmstring); + /* Select the item and scroll it into view. */ + XmListSelectPos (list, item_pos, True); + XmListSetPos (list, item_pos); + } + + XmStringFree (default_xmstring); } + record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0)); + /* Process events until the user presses Cancel or OK. */ + x_menu_set_in_use (1); result = 0; while (result == 0) { XEvent event; + x_menu_wait_for_event (0); XtAppNextEvent (Xt_app_con, &event); - (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f) ); + if (event.type == KeyPress + && FRAME_X_DISPLAY (f) == event.xkey.display) + { + KeySym keysym = XLookupKeysym (&event.xkey, 0); + + /* Pop down on C-g. */ + if (keysym == XK_g && (event.xkey.state & ControlMask) != 0) + XtUnmanageChild (dialog); + } + + (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f)); } /* Get the result. */ @@ -5176,9 +5403,6 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) else file = Qnil; - /* Clean up. */ - XtUnmanageChild (dialog); - XtDestroyWidget (dialog); UNBLOCK_INPUT; UNGCPRO; @@ -5193,28 +5417,42 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) #ifdef USE_GTK -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, - "Read file name, prompting with PROMPT in directory DIR.\n\ -Use a file selection dialog.\n\ -Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ -specified. Don't let the user enter a file name in the file\n\ -selection dialog's entry field, if MUSTMATCH is non-nil.") - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +static Lisp_Object +clean_up_dialog (arg) + Lisp_Object arg; +{ + x_menu_set_in_use (0); + + return Qnil; +} + +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, + doc: /* Read file name, prompting with PROMPT in directory DIR. +Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file +selection box, if specified. If MUSTMATCH is non-nil, the returned file +or directory must exist. If ONLY-DIR-P is non-nil, the user can only select +directories. */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { FRAME_PTR f = SELECTED_FRAME (); char *fn; Lisp_Object file = Qnil; - int count = specpdl_ptr - specpdl; - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + int count = SPECPDL_INDEX (); + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; char *cdef_file; - GCPRO5 (prompt, dir, default_filename, mustmatch, file); + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); + + if (popup_activated ()) + error ("Trying to use a menu from within a menu-entry"); + CHECK_STRING (prompt); CHECK_STRING (dir); /* Prevent redisplay. */ specbind (Qinhibit_redisplay, Qt); + record_unwind_protect (clean_up_dialog, Qnil); BLOCK_INPUT; @@ -5223,7 +5461,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil.") else cdef_file = SDATA (dir); - fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch)); + fn = xg_get_file_name (f, SDATA (prompt), cdef_file, + ! NILP (mustmatch), + ! NILP (only_dir_p)); if (fn) { @@ -5289,6 +5529,22 @@ usual X keysyms. */) return Qnil; } + /* In this code we check that the keyboard has physical keys with names + that start with BKSP (Backspace) and DELE (Delete), and that they + generate keysym XK_BackSpace and XK_Delete respectively. + This function is used to test if normal-erase-is-backspace should be + turned on. + An alternative approach would be to just check if XK_BackSpace and + XK_Delete are mapped to any key. But if any of those are mapped to + some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the + user doesn't know about it, it is better to return false here. + It is more obvious to the user what to do if she/he has two keys + clearly marked with names/symbols and one key does something not + expected (i.e. she/he then tries the other). + The cases where Backspace/Delete is mapped to some other key combination + are rare, and in those cases, normal-erase-is-backspace can be turned on + manually. */ + have_keys = Qnil; kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd); if (kb) @@ -5480,6 +5736,14 @@ such a font. This is especially effective for such large fonts as Chinese, Japanese, and Korean. */); Vx_pixel_size_width_font_regexp = Qnil; +/* This is not ifdef:ed, so other builds than GTK can customize it. */ + DEFVAR_BOOL ("x-use-old-gtk-file-dialog", &x_use_old_gtk_file_dialog, + doc: /* *Non-nil means prompt with the old GTK file selection dialog. +If nil or if the file selection dialog is not available, the new GTK file +chooser is used instead. To turn off all file dialogs set the +variable `use-file-dialog'. */); + x_use_old_gtk_file_dialog = 0; + #ifdef USE_X_TOOLKIT Fprovide (intern ("x-toolkit"), Qnil); #ifdef USE_MOTIF