X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5b3f855065861039e69524160f62e537dde517cc..3dfed6538787f747b1f76a90cae5e2ddce7352f5:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index 6aaba582e5..396ef8ceb6 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, 2006 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 @@ -155,6 +154,14 @@ int display_hourglass_p; int x_use_old_gtk_file_dialog; +/* If non-zero, by default show hidden files in the GTK file chooser. */ + +int x_gtk_show_hidden_files; + +/* If non-zero, don't collapse to tool bar when it is detached. */ + +int x_gtk_whole_detached_tool_bar; + /* The background and shape of the mouse pointer, and shape when not over text or in the modeline. */ @@ -570,11 +577,9 @@ x_real_positions (f, xptr, yptr) int had_errors = 0; Window win = f->output_data.x->parent_desc; - int count; - BLOCK_INPUT; - count = x_catch_errors (FRAME_X_DISPLAY (f)); + x_catch_errors (FRAME_X_DISPLAY (f)); if (win == FRAME_X_DISPLAY_INFO (f)->root_window) win = FRAME_OUTER_WINDOW (f); @@ -609,7 +614,7 @@ x_real_positions (f, xptr, yptr) if (! had_errors) { - int ign; + unsigned int ign; Window child, rootw; /* Get the real coordinates for the WM window upper left corner */ @@ -661,7 +666,7 @@ x_real_positions (f, xptr, yptr) had_errors = x_had_errors_p (FRAME_X_DISPLAY (f)); } - x_uncatch_errors (FRAME_X_DISPLAY (f), count); + x_uncatch_errors (); UNBLOCK_INPUT; @@ -783,21 +788,16 @@ xg_set_icon (f, file) FRAME_PTR f; Lisp_Object file; { - struct gcpro gcpro1; int result = 0; Lisp_Object found; - GCPRO1 (found); - found = x_find_image_file (file); if (! NILP (found)) { GdkPixbuf *pixbuf; GError *err = NULL; - char *filename; - - filename = SDATA (found); + char *filename = (char *) SDATA (found); BLOCK_INPUT; pixbuf = gdk_pixbuf_new_from_file (filename, &err); @@ -816,9 +816,24 @@ xg_set_icon (f, file) UNBLOCK_INPUT; } - UNGCPRO; return result; } + +int +xg_set_icon_from_xpm_data (f, data) + FRAME_PTR f; + char **data; +{ + int result = 0; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data); + + if (!pixbuf) + return 0; + + gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf); + g_object_unref (pixbuf); + return 1; +} #endif /* USE_GTK */ @@ -925,7 +940,6 @@ x_set_mouse_color (f, arg, oldval) Display *dpy = FRAME_X_DISPLAY (f); Cursor cursor, nontext_cursor, mode_cursor, hand_cursor; Cursor hourglass_cursor, horizontal_drag_cursor; - int count; unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); unsigned long mask_color = x->background_pixel; @@ -942,7 +956,7 @@ x_set_mouse_color (f, arg, oldval) BLOCK_INPUT; /* It's not okay to crash if the user selects a screwy cursor. */ - count = x_catch_errors (dpy); + x_catch_errors (dpy); if (!NILP (Vx_pointer_shape)) { @@ -1003,7 +1017,7 @@ x_set_mouse_color (f, arg, oldval) /* Check and report errors with the above calls. */ x_check_errors (dpy, "can't set cursor shape: %s"); - x_uncatch_errors (dpy, count); + x_uncatch_errors (); { XColor fore_color, back_color; @@ -1398,10 +1412,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); @@ -1512,11 +1530,12 @@ x_set_scroll_bar_background (f, value, oldval) Otherwise store 0 in *STRINGP, which means that the `encoding' of the result should be `COMPOUND_TEXT'. */ -unsigned char * -x_encode_text (string, coding_system, selectionp, text_bytes, stringp) +static unsigned char * +x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep) Lisp_Object string, coding_system; int *text_bytes, *stringp; int selectionp; + int *freep; { unsigned char *str = SDATA (string); int chars = SCHARS (string); @@ -1533,6 +1552,7 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp) /* No multibyte character in OBJ. We need not encode it. */ *text_bytes = bytes; *stringp = 1; + *freep = 0; return str; } @@ -1560,6 +1580,7 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp) *stringp = (charset_info == 1 || (!EQ (coding_system, Qcompound_text) && !EQ (coding_system, Qcompound_text_with_extensions))); + *freep = 1; return buf; } @@ -1598,16 +1619,13 @@ x_set_name_internal (f, name) in the future which can encode all Unicode characters. But, for the moment, there's no way to know that the current window manager supports it or not. */ - text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp); + text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp, + &do_free_text_value); text.encoding = (stringp ? XA_STRING : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); text.format = 8; text.nitems = bytes; - /* Check early, because ENCODE_UTF_8 below may GC and name may be - relocated. */ - do_free_text_value = text.value != SDATA (name); - if (NILP (f->icon_name)) { icon = text; @@ -1616,17 +1634,16 @@ x_set_name_internal (f, name) { /* See the above comment "Note: Encoding strategy". */ icon.value = x_encode_text (f->icon_name, coding_system, 0, - &bytes, &stringp); + &bytes, &stringp, &do_free_icon_value); icon.encoding = (stringp ? XA_STRING : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); icon.format = 8; icon.nitems = bytes; - do_free_icon_value = icon.value != SDATA (f->icon_name); } #ifdef USE_GTK gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - SDATA (ENCODE_UTF_8 (name))); + (char *) SDATA (ENCODE_UTF_8 (name))); #else /* not USE_GTK */ XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text); #endif /* not USE_GTK */ @@ -1876,7 +1893,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; @@ -1885,20 +1903,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]; @@ -1947,6 +1972,114 @@ static XIMStyle supported_xim_styles[] = /* 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; @@ -1958,6 +2091,9 @@ xic_create_xfontset (f, base_fontname) 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) { @@ -1974,12 +2110,15 @@ xic_create_xfontset (f, base_fontname) if (!xfs) { + char *fontsetname = xic_create_fontsetname (base_fontname, False); + /* New fontset. */ xfs = XCreateFontSet (FRAME_X_DISPLAY (f), - base_fontname, &missing_list, + fontsetname, &missing_list, &missing_count, &def_string); if (missing_list) XFreeStringList (missing_list); + xfree (fontsetname); } if (FRAME_XIC_BASE_FONTNAME (f)) @@ -2061,6 +2200,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) { @@ -2068,52 +2212,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) @@ -2716,12 +2817,15 @@ x_icon (f, parms) if (! EQ (icon_x, Qunbound)) x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y)); +#if 0 /* x_get_arg removes the visibility parameter as a side effect, + but x_create_frame still needs it. */ /* Start up iconic or window? */ x_wm_set_window_state (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon) ? IconicState : NormalState)); +#endif x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name) ? f->icon_name @@ -2904,6 +3008,8 @@ This function is an internal primitive--use `make-frame' instead. */) check_x (); + parms = Fcopy_alist (parms); + /* Use this general default value to start with until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; @@ -3191,7 +3297,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* We need to do this after creating the X window, so that the icon-creation functions can say whose icon they're describing. */ - x_default_parameter (f, parms, Qicon_type, Qnil, + x_default_parameter (f, parms, Qicon_type, Qt, "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL); x_default_parameter (f, parms, Qauto_raise, Qnil, @@ -3269,10 +3375,23 @@ This function is an internal primitive--use `make-frame' instead. */) FRAME_OUTER_WINDOW (f), dpyinfo->Xatom_wm_client_leader, XA_WINDOW, 32, PropModeReplace, - (char *) &dpyinfo->client_leader_window, 1); + (unsigned char *) &dpyinfo->client_leader_window, 1); UNBLOCK_INPUT; } + /* Initialize `default-minibuffer-frame' in case this is the first + frame on this display device. */ + if (FRAME_HAS_MINIBUF_P (f) + && (!FRAMEP (kb->Vdefault_minibuffer_frame) + || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))) + kb->Vdefault_minibuffer_frame = frame; + + /* All remaining specified parameters, which have not been "used" + by x_get_arg and friends, now go in the misc. alist of the frame. */ + for (tem = parms; !NILP (tem); tem = XCDR (tem)) + if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem)))) + f->param_alist = Fcons (XCAR (tem), f->param_alist); + UNGCPRO; /* Make sure windows on this frame appear in calls to next-window @@ -3318,13 +3437,12 @@ FRAME nil means use the selected frame. */) { struct frame *f = check_x_frame (frame); Display *dpy = FRAME_X_DISPLAY (f); - int count; BLOCK_INPUT; - count = x_catch_errors (dpy); + x_catch_errors (dpy); XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), RevertToParent, CurrentTime); - x_uncatch_errors (dpy, count); + x_uncatch_errors (); UNBLOCK_INPUT; return Qnil; @@ -4067,8 +4185,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); } @@ -4147,7 +4270,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; @@ -4187,7 +4310,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; @@ -4200,14 +4323,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); @@ -4250,6 +4397,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. */ @@ -4259,6 +4414,10 @@ start_hourglass () EMACS_TIME delay; int secs, usecs = 0; + /* Don't bother for ttys. */ + if (NILP (Vwindow_system)) + return; + cancel_hourglass (); if (INTEGERP (Vhourglass_delay) @@ -4477,9 +4636,7 @@ x_create_tip_frame (dpyinfo, parms, text) 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; + parms = Fcopy_alist (parms); #ifdef MULTI_KBOARD kb = dpyinfo->kboard; @@ -4493,7 +4650,6 @@ x_create_tip_frame (dpyinfo, parms, text) && !EQ (name, Qunbound) && !NILP (name)) error ("Invalid frame name--not a string or nil"); - Vx_resource_name = name; frame = Qnil; GCPRO3 (parms, name, frame); @@ -4796,16 +4952,22 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) if (INTEGERP (top)) *root_y = XINT (top); - else if (*root_y + XINT (dy) - height < 0) - *root_y -= XINT (dy); - else - { - *root_y -= height; + else if (*root_y + XINT (dy) <= 0) + *root_y = 0; /* Can happen for negative dy */ + else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height) + /* It fits below the pointer */ *root_y += XINT (dy); - } + else if (height + XINT (dy) <= *root_y) + /* It fits above the pointer. */ + *root_y -= height + XINT (dy); + else + /* Put it on the top. */ + *root_y = 0; if (INTEGERP (left)) *root_x = XINT (left); + else if (*root_x + XINT (dx) <= 0) + *root_x = 0; /* Can happen for negative dx */ else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width) /* It fits to the right of the pointer. */ *root_x += XINT (dx); @@ -4962,7 +5124,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; @@ -5086,8 +5248,27 @@ Value is t if tooltip was open, nil otherwise. */) File selection dialog ***********************************************************************/ -#ifdef USE_MOTIF +DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog, + Sx_uses_old_gtk_dialog, + 0, 0, 0, + doc: /* Return t if the old Gtk+ file selection dialog is used. */) + () +{ +#ifdef USE_GTK + extern int use_dialog_box; + extern int use_file_dialog; + if (use_dialog_box + && use_file_dialog + && have_menus_p () + && xg_uses_old_file_dialog ()) + return Qt; +#endif + return Qnil; +} + + +#ifdef USE_MOTIF /* Callback for "OK" and "Cancel" on file selection dialog. */ static void @@ -5144,6 +5325,7 @@ or directory must exist. ONLY-DIR-P is ignored." */) int result; struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; + Lisp_Object decoded_file; Widget dialog, text, help; Arg al[10]; int ac = 0; @@ -5284,7 +5466,9 @@ or directory must exist. ONLY-DIR-P is ignored." */) if (NILP (file)) Fsignal (Qquit, Qnil); - return unbind_to (count, file); + decoded_file = DECODE_FILE (file); + + return unbind_to (count, decoded_file); } #endif /* USE_MOTIF */ @@ -5312,6 +5496,7 @@ directories. */) FRAME_PTR f = SELECTED_FRAME (); char *fn; Lisp_Object file = Qnil; + Lisp_Object decoded_file; int count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; char *cdef_file; @@ -5352,7 +5537,9 @@ directories. */) if (NILP (file)) Fsignal (Qquit, Qnil); - return unbind_to (count, file); + decoded_file = DECODE_FILE (file); + + return unbind_to (count, decoded_file); } #endif /* USE_GTK */ @@ -5372,7 +5559,8 @@ DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p, doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME. FRAME nil means use the selected frame. Value is t if we know that both keys are present, and are mapped to the -usual X keysyms. */) +usual X keysyms. Value is `lambda' if we cannot determine if both keys are +present and mapped to the usual X keysyms. */) (frame) Lisp_Object frame; { @@ -5391,7 +5579,7 @@ usual X keysyms. */) if (!XkbLibraryVersion (&major, &minor)) { UNBLOCK_INPUT; - return Qnil; + return Qlambda; } /* Check that the server supports XKB. */ @@ -5400,9 +5588,25 @@ usual X keysyms. */) if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor)) { UNBLOCK_INPUT; - return Qnil; + return Qlambda; } + /* 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) @@ -5439,7 +5643,7 @@ usual X keysyms. */) UNBLOCK_INPUT; return have_keys; #else /* not HAVE_XKBGETKEYBOARD */ - return Qnil; + return Qlambda; #endif /* not HAVE_XKBGETKEYBOARD */ } @@ -5602,6 +5806,20 @@ chooser is used instead. To turn off all file dialogs set the variable `use-file-dialog'. */); x_use_old_gtk_file_dialog = 0; + DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files, + doc: /* *If non-nil, the GTK file chooser will by default show hidden files. +Note that this is just the default, there is a toggle button on the file +chooser to show or not show hidden files on a case by case basis. */); + x_gtk_show_hidden_files = 0; + + DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar, + doc: /* *If non-nil, a detached tool bar is shown in full. +The default is to just show an arrow and pressing on that arrow shows +the tool bar buttons. */); + x_gtk_whole_detached_tool_bar = 0; + + Fprovide (intern ("x"), Qnil); + #ifdef USE_X_TOOLKIT Fprovide (intern ("x-toolkit"), Qnil); #ifdef USE_MOTIF @@ -5688,6 +5906,7 @@ variable `use-file-dialog'. */); last_show_tip_args = Qnil; staticpro (&last_show_tip_args); + defsubr (&Sx_uses_old_gtk_dialog); #if defined (USE_MOTIF) || defined (USE_GTK) defsubr (&Sx_file_dialog); #endif