*** empty log message ***
[bpt/emacs.git] / src / xfns.c
index 8f7e133..e33ce55 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions for the X window system.
-   Copyright (C) 1989, 92, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02
      Free Software Foundation.
 
 This file is part of GNU Emacs.
@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #include "keyboard.h"
 #include "blockinput.h"
 #include <epaths.h>
+#include "character.h"
 #include "charset.h"
 #include "coding.h"
 #include "fontset.h"
@@ -219,6 +220,10 @@ Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
 Lisp_Object Qscreen_gamma, Qline_spacing, Qcenter;
 Lisp_Object Qcompound_text, Qcancel_timer;
 Lisp_Object Qwait_for_wm;
+Lisp_Object Qfullscreen;
+Lisp_Object Qfullwidth;
+Lisp_Object Qfullheight;
+Lisp_Object Qfullboth;
 
 /* The below are defined in frame.c.  */
 
@@ -733,6 +738,7 @@ static void x_disable_image P_ ((struct frame *, struct image *));
 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));
 static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
@@ -740,6 +746,7 @@ void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_internal_border_width P_ ((struct frame *, Lisp_Object,
@@ -777,32 +784,36 @@ static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
 
 static struct x_frame_parm_table x_frame_parms[] =
 {
-  "auto-raise",                        x_set_autoraise,
-  "auto-lower",                        x_set_autolower,
-  "background-color",          x_set_background_color,
-  "border-color",              x_set_border_color,
-  "border-width",              x_set_border_width,
-  "cursor-color",              x_set_cursor_color,
-  "cursor-type",               x_set_cursor_type,
-  "font",                      x_set_font,
-  "foreground-color",          x_set_foreground_color,
-  "icon-name",                 x_set_icon_name,
-  "icon-type",                 x_set_icon_type,
-  "internal-border-width",     x_set_internal_border_width,
-  "menu-bar-lines",            x_set_menu_bar_lines,
-  "mouse-color",               x_set_mouse_color,
-  "name",                      x_explicitly_set_name,
-  "scroll-bar-width",          x_set_scroll_bar_width,
-  "title",                     x_set_title,
-  "unsplittable",              x_set_unsplittable,
-  "vertical-scroll-bars",      x_set_vertical_scroll_bars,
-  "visibility",                        x_set_visibility,
-  "tool-bar-lines",            x_set_tool_bar_lines,
-  "scroll-bar-foreground",     x_set_scroll_bar_foreground,
-  "scroll-bar-background",     x_set_scroll_bar_background,
-  "screen-gamma",              x_set_screen_gamma,
-  "line-spacing",              x_set_line_spacing,
-  "wait-for-wm",               x_set_wait_for_wm
+  {"auto-raise",               x_set_autoraise},
+  {"auto-lower",               x_set_autolower},
+  {"background-color",         x_set_background_color},
+  {"border-color",             x_set_border_color},
+  {"border-width",             x_set_border_width},
+  {"cursor-color",             x_set_cursor_color},
+  {"cursor-type",              x_set_cursor_type},
+  {"font",                     x_set_font},
+  {"foreground-color",         x_set_foreground_color},
+  {"icon-name",                        x_set_icon_name},
+  {"icon-type",                        x_set_icon_type},
+  {"internal-border-width",    x_set_internal_border_width},
+  {"menu-bar-lines",           x_set_menu_bar_lines},
+  {"mouse-color",              x_set_mouse_color},
+  {"name",                     x_explicitly_set_name},
+  {"scroll-bar-width",         x_set_scroll_bar_width},
+  {"title",                    x_set_title},
+  {"unsplittable",             x_set_unsplittable},
+  {"vertical-scroll-bars",     x_set_vertical_scroll_bars},
+  {"visibility",               x_set_visibility},
+  {"tool-bar-lines",           x_set_tool_bar_lines},
+  {"scroll-bar-foreground",    x_set_scroll_bar_foreground},
+  {"scroll-bar-background",    x_set_scroll_bar_background},
+  {"screen-gamma",             x_set_screen_gamma},
+  {"line-spacing",             x_set_line_spacing},
+  {"left-fringe",              x_set_fringe_width},
+  {"right-fringe",             x_set_fringe_width},
+  {"wait-for-wm",              x_set_wait_for_wm},
+  {"fullscreen",                x_set_fullscreen},
+  
 };
 
 /* Attach the `x-frame-parameter' properties to
@@ -818,6 +829,28 @@ init_x_parm_symbols ()
          make_number (i));
 }
 \f
+
+/* Really try to move where we want to be in case of fullscreen.  Some WMs
+   moves the window where we tell them.  Some (mwm, twm) moves the outer
+   window manager window there instead.
+   Try to compensate for those WM here. */
+static void
+x_fullscreen_move (f, new_top, new_left)
+     struct frame *f;
+     int new_top;
+     int new_left;
+{
+  if (new_top != f->output_data.x->top_pos
+      || new_left != f->output_data.x->left_pos)
+    {
+      int move_x = new_left + f->output_data.x->x_pixels_outer_diff;
+      int move_y = new_top + f->output_data.x->y_pixels_outer_diff;
+
+      f->output_data.x->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
+      x_set_offset (f, move_x, move_y, 1);
+    }
+}
+
 /* Change the parameters of frame F as specified by ALIST.
    If a parameter is not specially recognized, do nothing special;
    otherwise call the `x_set_...' function for that parameter.
@@ -848,6 +881,7 @@ x_set_frame_parameters (f, alist)
   int i, p;
   int left_no_change = 0, top_no_change = 0;
   int icon_left_no_change = 0, icon_top_no_change = 0;
+  int fullscreen_is_being_set = 0;
 
   struct gcpro gcpro1, gcpro2;
 
@@ -896,23 +930,34 @@ x_set_frame_parameters (f, alist)
   /* Process foreground_color and background_color before anything else.
      They are independent of other properties, but other properties (e.g.,
      cursor_color) are dependent upon them.  */
+  /* Process default font as well, since fringe widths depends on it.  */
+  /* Also, process fullscreen, width and height depend upon that */
   for (p = 0; p < i; p++) 
     {
       Lisp_Object prop, val;
 
       prop = parms[p];
       val = values[p];
-      if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+      if (EQ (prop, Qforeground_color)
+         || EQ (prop, Qbackground_color)
+         || EQ (prop, Qfont)
+          || EQ (prop, Qfullscreen))
        {
          register Lisp_Object param_index, old_value;
 
-         param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
-         store_frame_param (f, prop, val);
-         if (NATNUMP (param_index)
-             && (XFASTINT (param_index)
-                 < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
-           (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+         fullscreen_is_being_set |= EQ (prop, Qfullscreen);
+         
+         if (NILP (Fequal (val, old_value)))
+           {
+             store_frame_param (f, prop, val);
+
+             param_index = Fget (prop, Qx_frame_parameter);
+             if (NATNUMP (param_index)
+                 && (XFASTINT (param_index)
+                     < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
+               (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+           }
        }
     }
 
@@ -936,17 +981,22 @@ x_set_frame_parameters (f, alist)
        icon_top = val;
       else if (EQ (prop, Qicon_left))
        icon_left = val;
-      else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+      else if (EQ (prop, Qforeground_color)
+              || EQ (prop, Qbackground_color)
+              || EQ (prop, Qfont)
+               || EQ (prop, Qfullscreen))
        /* Processed above.  */
        continue;
       else
        {
          register Lisp_Object param_index, old_value;
 
-         param_index = Fget (prop, Qx_frame_parameter);
          old_value = get_frame_param (f, prop);
+
          store_frame_param (f, prop, val);
-         if (NATNUMP (param_index)
+
+         param_index = Fget (prop, Qx_frame_parameter);
+         if (NATNUMP (param_index)
              && (XFASTINT (param_index)
                  < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
            (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
@@ -987,6 +1037,21 @@ x_set_frame_parameters (f, alist)
        XSETINT (icon_top, 0);
     }
 
+  if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
+    {
+      /* If the frame is visible already and the fullscreen parameter is
+         being set, it is too late to set WM manager hints to specify
+         size and position.
+         Here we first get the width, height and position that applies to
+         fullscreen.  We then move the frame to the appropriate
+         position.  Resize of the frame is taken care of in the code after
+         this if-statement. */
+      int new_left, new_top;
+      
+      x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
+      x_fullscreen_move (f, new_top, new_left);
+    }
+  
   /* 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
@@ -1089,70 +1154,109 @@ x_real_positions (f, xptr, yptr)
      FRAME_PTR f;
      int *xptr, *yptr;
 {
-  int win_x, win_y;
-  Window child;
+  int win_x, win_y, outer_x, outer_y;
+  int real_x = 0, real_y = 0;
+  int had_errors = 0;
+  Window win = f->output_data.x->parent_desc;
 
-  /* This is pretty gross, but seems to be the easiest way out of
-     the problem that arises when restarting window-managers.  */
+  int count;
 
-#ifdef USE_X_TOOLKIT
-  Window outer = (f->output_data.x->widget
-                 ? XtWindow (f->output_data.x->widget)
-                 : FRAME_X_WINDOW (f));
-#else
-  Window outer = f->output_data.x->window_desc;
-#endif
-  Window tmp_root_window;
-  Window *tmp_children;
-  unsigned int tmp_nchildren;
+  BLOCK_INPUT;
 
-  while (1)
+  count = x_catch_errors (FRAME_X_DISPLAY (f));
+
+  if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
+    win = FRAME_OUTER_WINDOW (f);
+
+  /* This loop traverses up the containment tree until we hit the root
+     window.  Window managers may intersect many windows between our window
+     and the root window.  The window we find just before the root window
+     should be the outer WM window. */
+  for (;;)
     {
-      int count = x_catch_errors (FRAME_X_DISPLAY (f));
-      Window outer_window;
+      Window wm_window, rootw;
+      Window *tmp_children;
+      unsigned int tmp_nchildren;
 
-      XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
-                 &f->output_data.x->parent_desc,
-                 &tmp_children, &tmp_nchildren);
+      XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
+                  &wm_window, &tmp_children, &tmp_nchildren);
       XFree ((char *) tmp_children);
 
-      win_x = win_y = 0;
+      had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
 
-      /* 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)
-       outer_window = f->output_data.x->parent_desc;
-      else
-       outer_window = outer;
+      if (wm_window == rootw || had_errors)
+        break;
 
+      win = wm_window;
+    }
+    
+  if (! had_errors)
+    {
+      int ign;
+      Window child, rootw;
+          
+      /* Get the real coordinates for the WM window upper left corner */
+      XGetGeometry (FRAME_X_DISPLAY (f), win,
+                    &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
+
+      /* Translate real coordinates to coordinates relative to our
+         window.  For our window, the upper left corner is 0, 0.
+         Since the upper left corner of the WM window is outside
+         our window, win_x and win_y will be negative:
+
+         ------------------          ---> x
+         |      title                |
+         | -----------------         v y
+         | |  our window
+      */
       XTranslateCoordinates (FRAME_X_DISPLAY (f),
 
                             /* From-window, to-window.  */
-                            outer_window,
                             FRAME_X_DISPLAY_INFO (f)->root_window,
+                             FRAME_X_WINDOW (f),
 
                             /* From-position, to-position.  */
-                            0, 0, &win_x, &win_y,
+                             real_x, real_y, &win_x, &win_y,
 
                             /* Child of win.  */
                             &child);
 
-      /* It is possible for the window returned by the XQueryNotify
-        to become invalid by the time we call XTranslateCoordinates.
-        That can happen when you restart some window managers.
-        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)))
+      if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
        {
-         x_uncatch_errors (FRAME_X_DISPLAY (f), count);
-         break;
+          outer_x = win_x;
+          outer_y = win_y;
        }
+      else
+        {
+          XTranslateCoordinates (FRAME_X_DISPLAY (f),
+
+                                 /* From-window, to-window.  */
+                                 FRAME_X_DISPLAY_INFO (f)->root_window,
+                                 FRAME_OUTER_WINDOW (f),
+                                     
+                                 /* From-position, to-position.  */
+                                 real_x, real_y, &outer_x, &outer_y,
+                         
+                                 /* Child of win.  */
+                                 &child);
+    }
 
-      x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+      had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
     }
+      
+  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+      
+  UNBLOCK_INPUT;
 
-  *xptr = win_x;
-  *yptr = win_y;
+  if (had_errors) return;
+      
+  f->output_data.x->x_pixels_diff = -win_x;
+  f->output_data.x->y_pixels_diff = -win_y;
+  f->output_data.x->x_pixels_outer_diff = -outer_x;
+  f->output_data.x->y_pixels_outer_diff = -outer_y;
+
+  *xptr = real_x;
+  *yptr = real_y;
 }
 
 /* Insert a description of internally-recorded parameters of frame X
@@ -1187,6 +1291,14 @@ x_report_frame_params (f, alistptr)
                   make_number (f->output_data.x->border_width));
   store_in_alist (alistptr, Qinternal_border_width,
                   make_number (f->output_data.x->internal_border_width));
+  store_in_alist (alistptr, Qleft_fringe,
+                  make_number (f->output_data.x->left_fringe_width));
+  store_in_alist (alistptr, Qright_fringe,
+                  make_number (f->output_data.x->right_fringe_width));
+  store_in_alist (alistptr, Qscroll_bar_width,
+           make_number (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+                        ? FRAME_SCROLL_BAR_PIXEL_WIDTH(f)
+                        : 0));
   sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
   store_in_alist (alistptr, Qwindow_id,
                   build_string (buf));
@@ -1328,6 +1440,25 @@ x_set_wait_for_wm (f, new_value, old_value)
 }
 
 
+/* Change the `fullscreen' frame parameter of frame F.  OLD_VALUE is
+   the previous value of that parameter, NEW_VALUE is the new value. */
+
+static void
+x_set_fullscreen (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  if (NILP (new_value))
+    f->output_data.x->want_fullscreen = FULLSCREEN_NONE;
+  else if (EQ (new_value, Qfullboth))
+    f->output_data.x->want_fullscreen = FULLSCREEN_BOTH;
+  else if (EQ (new_value, Qfullwidth))
+    f->output_data.x->want_fullscreen = FULLSCREEN_WIDTH;
+  else if (EQ (new_value, Qfullheight))
+    f->output_data.x->want_fullscreen = FULLSCREEN_HEIGHT;
+}
+
+
 /* Change the `screen-gamma' frame parameter of frame F.  OLD_VALUE is
    the previous value of that parameter, NEW_VALUE is the new
    value.  */
@@ -1858,7 +1989,7 @@ x_set_font (f, arg, oldval)
   BLOCK_INPUT;
   result = (STRINGP (fontset_name)
            ? x_new_fontset (f, XSTRING (fontset_name)->data)
-           : x_new_font (f, XSTRING (arg)->data));
+           : x_new_fontset (f, XSTRING (arg)->data));
   UNBLOCK_INPUT;
   
   if (EQ (result, Qnil))
@@ -1874,10 +2005,10 @@ x_set_font (f, arg, oldval)
          if (old_fontset == f->output_data.x->fontset)
            return;
        }
-      else if (!NILP (Fequal (result, oldval)))
+      store_frame_param (f, Qfont, result);
+      if (!NILP (Fequal (result, oldval)))
        return;
       
-      store_frame_param (f, Qfont, result);
       recompute_basic_faces (f);
     }
   else
@@ -1897,6 +2028,14 @@ x_set_font (f, arg, oldval)
     }
 }
 
+static void
+x_set_fringe_width (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  x_compute_fringe_widths (f, 1);
+}
+
 void
 x_set_border_width (f, arg, oldval)
      struct frame *f;
@@ -2207,6 +2346,10 @@ x_set_scroll_bar_background (f, value, oldval)
    CODING_SYSTEM, and return a newly allocated memory area which
    should be freed by `xfree' by a caller.
 
+   SELECTIONP non-zero means the string is being encoded for an X
+   selection, so it is safe to run pre-write conversions (which
+   may run Lisp code).
+
    Store the byte length of resulting text in *TEXT_BYTES.
 
    If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
@@ -2215,41 +2358,34 @@ x_set_scroll_bar_background (f, value, oldval)
    the result should be `COMPOUND_TEXT'.  */
 
 unsigned char *
-x_encode_text (string, coding_system, text_bytes, stringp)
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
      Lisp_Object string, coding_system;
      int *text_bytes, *stringp;
+     int selectionp;
 {
-  unsigned char *str = XSTRING (string)->data;
-  int chars = XSTRING (string)->size;
-  int bytes = STRING_BYTES (XSTRING (string));
-  int charset_info;
-  int bufsize;
-  unsigned char *buf;
+  int result = string_xstring_p (string);
   struct coding_system coding;
 
-  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 = STRING_BYTES (XSTRING (string));
       *stringp = 1;
-      return str;
+      return XSTRING (string)->data;
     }
 
   setup_coding_system (coding_system, &coding);
-  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 = XSTRING (string)->size * 2;
+  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+  encode_coding_object (&coding, string, 0, 0,
+                       XSTRING (string)->size,
+                       STRING_BYTES (XSTRING (string)), Qnil);
   *text_bytes = coding.produced;
-  *stringp = (charset_info == 1 || !EQ (coding_system, Qcompound_text));
-  return buf;
+  *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
+  return coding.destination;
 }
 
 \f
@@ -2320,7 +2456,7 @@ x_set_name (f, name, explicit)
        coding_system = Vlocale_coding_system;
        if (NILP (coding_system))
          coding_system = Qcompound_text;
-       text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
@@ -2332,7 +2468,7 @@ x_set_name (f, name, explicit)
          }
        else
          {
-           icon.value = x_encode_text (f->icon_name, coding_system,
+           icon.value = x_encode_text (f->icon_name, coding_system, 0,
                                        &bytes, &stringp);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -2427,7 +2563,7 @@ x_set_title (f, name, old_name)
        coding_system = Vlocale_coding_system;
        if (NILP (coding_system))
          coding_system = Qcompound_text;
-       text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+       text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
        text.format = 8;
@@ -2439,7 +2575,7 @@ x_set_title (f, name, old_name)
          }
        else
          {
-           icon.value = x_encode_text (f->icon_name, coding_system,
+           icon.value = x_encode_text (f->icon_name, coding_system, 0,
                                        &bytes, &stringp);
            icon.encoding = (stringp ? XA_STRING
                             : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -3113,8 +3249,9 @@ x_figure_window_size (f, parms)
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
        ? 0
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
-  f->output_data.x->flags_areas_extra
-    = FRAME_FLAGS_AREA_WIDTH (f);
+
+  x_compute_fringe_widths (f, 0);
+
   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);
 
@@ -3185,6 +3322,22 @@ x_figure_window_size (f, parms)
        window_prompting |= PPosition;
     }
 
+  if (f->output_data.x->want_fullscreen != FULLSCREEN_NONE)
+    {
+      int left, top;
+      int width, height;
+      
+      /* It takes both for some WM:s to place it where we want */
+      window_prompting = USPosition | PPosition;
+      x_fullscreen_adjust (f, &width, &height, &top, &left);
+      f->width = width;
+      f->height = height;
+      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);
+      f->output_data.x->left_pos = left;
+      f->output_data.x->top_pos = top;
+    }
+  
   return window_prompting;
 }
 
@@ -4276,28 +4429,22 @@ This function is an internal primitive--use `make-frame' instead.  */)
     BLOCK_INPUT;
     /* First, try whatever font the caller has specified.  */
     if (STRINGP (font))
-      {
-       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);
-      }
+      font = x_new_fontset (f, XSTRING (font)->data);
     
     /* 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");
+      font = x_new_fontset (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");
+      font = x_new_fontset (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");
+      font = x_new_fontset (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");
+      font = x_new_fontset (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");
+      font = x_new_fontset (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
     UNBLOCK_INPUT;
     if (! STRINGP (font))
       font = build_string ("fixed");
@@ -4315,7 +4462,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
   
-  /* This defaults to 2 in order to match xterm.  We recognize either
+  /* This defaults to 1 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
      it).  */
   if (NILP (Fassq (Qinternal_border_width, parms)))
@@ -4350,6 +4497,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
                       "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
   x_default_parameter (f, parms, Qline_spacing, Qnil,
                       "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qleft_fringe, Qnil,
+                      "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qright_fringe, Qnil,
+                      "rightFringe", "RightFringe", RES_TYPE_NUMBER);
 
   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
                                        "scrollBarForeground",
@@ -4377,6 +4528,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
                       "title", "Title", RES_TYPE_STRING);
   x_default_parameter (f, parms, Qwait_for_wm, Qt,
                       "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
+  x_default_parameter (f, parms, Qfullscreen, Qnil,
+                       "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
   f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
 
@@ -4390,7 +4543,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
     {
       int margin, relief, bar_height;
       
-      relief = (tool_bar_button_relief > 0
+      relief = (tool_bar_button_relief >= 0
                ? tool_bar_button_relief
                : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
 
@@ -4969,7 +5122,7 @@ visual_classes[] =
   {"PseudoColor",      PseudoColor},
   {"TrueColor",                TrueColor},
   {"DirectColor",      DirectColor},
-  NULL
+  {NULL, 0}
 };
 
 
@@ -6445,6 +6598,7 @@ x_put_x_image (f, ximg, pixmap, width, height)
      struct frame *f;
      XImage *ximg;
      Pixmap pixmap;
+     int width, height;
 {
   GC gc;
   
@@ -9079,17 +9233,16 @@ png_load (f, img)
 /* Work around a warning about HAVE_STDLIB_H being redefined in
    jconfig.h.  */
 #ifdef HAVE_STDLIB_H
-#define HAVE_STDLIB_H_1
-#undef HAVE_STDLIB_H
-#endif /* HAVE_STLIB_H */
-
-#include <jpeglib.h>
+#  undef HAVE_STDLIB_H
+#  include <jpeglib.h>
+#  undef HAVE_STDLIB_H
+#  define HAVE_STDLIB_H 1
+#else
+#  include <jpeglib.h>
+#endif /* HAVE_STDLIB_H */
 #include <jerror.h>
-#include <setjmp.h>
 
-#ifdef HAVE_STLIB_H_1
-#define HAVE_STDLIB_H 1
-#endif
+#include <setjmp.h>
 
 static int jpeg_image_p P_ ((Lisp_Object object));
 static int jpeg_load P_ ((struct frame *f, struct image *img));
@@ -10000,8 +10153,8 @@ gif_load (f, img)
       return 0;
     }
 
-  width = img->width = gif->SWidth;
-  height = img->height = gif->SHeight;
+  width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+  height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
 
   /* Create the X image and pixmap.  */
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
@@ -11070,7 +11223,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
   
   /* Move the tooltip window where the mouse pointer is.  Resize and
      show it.  */
-  if (!INTEGERP (left) && !INTEGERP (top))
+  if (!INTEGERP (left) || !INTEGERP (top))
     {
       BLOCK_INPUT;
       XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
@@ -11090,10 +11243,15 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
 
   if (INTEGERP (left))
     *root_x = XINT (left);
-  else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width)
+  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);
+  else if (width + XINT (dx) <= *root_x)
+    /* It fits to the left of the pointer.  */
     *root_x -= width + XINT (dx);
   else
-    *root_x += XINT (dx);
+    /* Put it left-justified on the screen--it ought to fit that way.  */
+    *root_x = 0;
 }
 
 
@@ -11719,6 +11877,14 @@ syms_of_xfns ()
   staticpro (&Qcancel_timer);
   Qwait_for_wm = intern ("wait-for-wm");
   staticpro (&Qwait_for_wm);
+  Qfullscreen = intern ("fullscreen");
+  staticpro (&Qfullscreen);
+  Qfullwidth = intern ("fullwidth");
+  staticpro (&Qfullwidth);
+  Qfullheight = intern ("fullheight");
+  staticpro (&Qfullheight);
+  Qfullboth = intern ("fullboth");
+  staticpro (&Qfullboth);
   /* This is the end of symbol initialization.  */
 
   /* Text property `display' should be nonsticky by default.  */
@@ -11926,6 +12092,7 @@ meaning don't clear the cache.  */);
   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;
 
   /* Images.  */