]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-54
[gnu-emacs] / src / xfns.c
index ee4a7bf3b004d1eb0dbc42d2e43ef26f1c421841..f52207f01c73814344916d448d5e80314aaf4092 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions for the X window system.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+                 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -41,6 +41,7 @@ Boston, MA 02110-1301, USA.  */
 #include "keyboard.h"
 #include "blockinput.h"
 #include <epaths.h>
+#include "character.h"
 #include "charset.h"
 #include "coding.h"
 #include "fontset.h"
@@ -154,6 +155,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.  */
 
@@ -569,11 +578,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);
@@ -660,7 +667,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;
 
@@ -782,12 +789,9 @@ 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))
@@ -813,7 +817,6 @@ xg_set_icon (f, file)
       UNBLOCK_INPUT;
     }
 
-  UNGCPRO;
   return result;
 }
 
@@ -938,7 +941,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;
 
@@ -955,7 +957,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))
     {
@@ -1016,7 +1018,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;
@@ -1536,51 +1538,30 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
      int selectionp;
      int *freep;
 {
-  unsigned char *str = SDATA (string);
-  int chars = SCHARS (string);
-  int bytes = SBYTES (string);
-  int charset_info;
-  int bufsize;
-  unsigned char *buf;
+  int result = string_xstring_p (string);
   struct coding_system coding;
-  extern Lisp_Object Qcompound_text_with_extensions;
 
-  charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
-  if (charset_info == 0)
+  if (result == 0)
     {
       /* No multibyte character in OBJ.  We need not encode it.  */
-      *text_bytes = bytes;
+      *text_bytes = SBYTES (string);
       *stringp = 1;
       *freep = 0;
-      return str;
+      return SDATA (string);
     }
 
   setup_coding_system (coding_system, &coding);
-  if (selectionp
-      && SYMBOLP (coding.pre_write_conversion)
-      && !NILP (Ffboundp (coding.pre_write_conversion)))
-    {
-      string = run_pre_post_conversion_on_str (string, &coding, 1);
-      str = SDATA (string);
-      chars = SCHARS (string);
-      bytes = SBYTES (string);
-    }
-  coding.src_multibyte = 1;
-  coding.dst_multibyte = 0;
-  coding.mode |= CODING_MODE_LAST_BLOCK;
-  if (coding.type == coding_type_iso2022)
-    coding.flags |= CODING_FLAG_ISO_SAFE;
+  coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
   /* We suppress producing escape sequences for composition.  */
-  coding.composing = COMPOSITION_DISABLED;
-  bufsize = encoding_buffer_size (&coding, bytes);
-  buf = (unsigned char *) xmalloc (bufsize);
-  encode_coding (&coding, str, buf, bytes, bufsize);
+  coding.common_flags &= ~CODING_ANNOTATION_MASK;
+  coding.dst_bytes = SCHARS (string) * 2;
+  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+  encode_coding_object (&coding, string, 0, 0,
+                       SCHARS (string), SBYTES (string), Qnil);
   *text_bytes = coding.produced;
-  *stringp = (charset_info == 1
-             || (!EQ (coding_system, Qcompound_text)
-                 && !EQ (coding_system, Qcompound_text_with_extensions)));
+  *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
   *freep = 1;
-  return buf;
+  return coding.destination;
 }
 
 \f
@@ -2816,12 +2797,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
@@ -3004,6 +2988,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;
@@ -3154,35 +3140,39 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
     font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
+    /* If the caller has specified no font, try out fonts which we
+       hope have bold and italic variations.  */
+    if (!STRINGP (font))
       {
-       tem = Fquery_fontset (font, Qnil);
-       if (STRINGP (tem))
-         font = x_new_fontset (f, SDATA (tem));
-       else
-         font = x_new_font (f, SDATA (font));
+       char *names[]
+         = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
+             "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+             "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+             /* This was formerly the first thing tried, but it finds
+                too many fonts and takes too long.  */
+             "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
+             /* If those didn't work, look for something which will
+                at least work.  */
+             "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
+             NULL };
+       int i;
+
+       BLOCK_INPUT;
+       for (i = 0; names[i]; i++)
+         {
+           Lisp_Object list;
+
+           list = x_list_fonts (f, build_string (names[i]), 0, 1);
+           if (CONSP (list))
+             {
+               font = XCAR (list);
+               break;
+             }
+         }
+       UNBLOCK_INPUT;
+       if (! STRINGP (font))
+         font = build_string ("fixed");
       }
-
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
-    if (!STRINGP (font))
-      font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      /* This was formerly the first thing tried, but it finds too many fonts
-        and takes too long.  */
-      font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("fixed");
-
     x_default_parameter (f, parms, Qfont, font,
                         "font", "Font", RES_TYPE_STRING);
   }
@@ -3380,6 +3370,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
           || !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
@@ -3425,13 +3421,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;
@@ -4625,6 +4620,7 @@ x_create_tip_frame (dpyinfo, parms, text)
 
   check_x ();
 
+  parms = Fcopy_alist (parms);
 
 #ifdef MULTI_KBOARD
   kb = dpyinfo->kboard;
@@ -4736,7 +4732,7 @@ x_create_tip_frame (dpyinfo, parms, text)
       {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
-         font = x_new_fontset (f, SDATA (tem));
+         font = x_new_fontset (f, tem);
        else
          font = x_new_font (f, SDATA (font));
       }
@@ -4940,19 +4936,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 if (*root_y + XINT (dy) >= FRAME_X_DISPLAY_INFO (f)->height)
-    /* Put tip above the pointer.  */
-    *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);
@@ -5233,8 +5232,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
@@ -5291,6 +5309,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;
@@ -5431,7 +5450,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 */
@@ -5459,6 +5480,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;
@@ -5499,7 +5521,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 */
@@ -5519,7 +5543,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;
 {
@@ -5538,7 +5563,7 @@ usual X keysyms.  */)
   if (!XkbLibraryVersion (&major, &minor))
     {
       UNBLOCK_INPUT;
-      return Qnil;
+      return Qlambda;
     }
 
   /* Check that the server supports XKB.  */
@@ -5547,7 +5572,7 @@ 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
@@ -5602,7 +5627,7 @@ usual X keysyms.  */)
   UNBLOCK_INPUT;
   return have_keys;
 #else /* not HAVE_XKBGETKEYBOARD */
-  return Qnil;
+  return Qlambda;
 #endif /* not HAVE_XKBGETKEYBOARD */
 }
 
@@ -5765,6 +5790,18 @@ 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
@@ -5838,6 +5875,7 @@ variable `use-file-dialog'.  */);
   find_ccl_program_func = x_find_ccl_program;
   query_font_func = x_query_font;
   set_frame_fontset_func = x_set_font;
+  get_font_repertory_func = x_get_font_repertory;
   check_window_system_func = check_x;
 
   hourglass_atimer = NULL;
@@ -5853,6 +5891,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