changeset 5080:5502045ec510

The background-placement face property. -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-02-25 Didier Verna <didier@xemacs.org> The background-placement face property. * cl-macs.el (face-background-placement): New defsetf. * cus-face.el (custom-face-attributes): * faces.el (face-interactive): * faces.el (set-face-property): * faces.el (face-equal): * faces.el (init-other-random-faces): Update. * faces.el (face-background-placement): * faces.el (set-face-background-placement): * faces.el (face-background-placement-instance): * faces.el (face-background-placement-instance-p): * frame.el (set-frame-background-placement): * frame.el (frame-background-placement): * frame.el (frame-background-placement-instance): * objects.el (make-face-background-placement-specifier): New. man/ChangeLog addition: 2010-02-25 Didier Verna <didier@xemacs.org> The background-placement face property. * xemacs/custom.texi (Faces): Document it. src/ChangeLog addition: 2010-02-25 Didier Verna <didier@xemacs.org> The background-placement face property. * console-x-impl.h (struct x_frame): Add new slots x and y. * console-x-impl.h (FRAME_X_X, FRAME_X_Y): New slot accessors. * console-gtk-impl.h: Fake something similar for potential port. * frame-x.c (x_get_frame_text_position): New function. * frame-x.c (x_init_frame_3): Use it. * event-Xt.c (emacs_Xt_handle_magic_event): Eat spurious ConfigureNotify events, get the frame position and mark frame faces changed. * objects-impl.h: The face_background_placement_specifier structure and its accessors. * objects.c: New symbols Qabsolute and Qrelative. * objects.c (face_background_placement_create): * objects.c (face_background_placement_mark): * objects.c (face_background_placement_instantiate): * objects.c (face_background_placement_validate): * objects.c (face_background_placement_after_change): * objects.c (set_face_background_placement_attached_to): New. * objects.h (set_face_background_palcement_attached_to): Declare the one above. * objects.c (syms_of_objects): * objects.c (specifier_type_create_objects): * objects.c (reinit_specifier_type_create_objects): * objects.c (reinit_vars_of_objects): Update for the modifications above. * console-xlike-inc.h (XLIKE_GC_TS_X_ORIGIN, XLIKE_GC_TS_X_ORIGIN): New X11/Gtk compatibility macros. * redisplay-xlike-inc.c (XLIKE_get_gc): Add a background placement argument and handle it. * gtk-glue.c (face_to_gc): * redisplay-xlike-inc.c (XLIKE_output_string): * redisplay-xlike-inc.c (XLIKE_output_pixmap): * redisplay-xlike-inc.c (XLIKE_output_blank): * redisplay-xlike-inc.c (XLIKE_output_horizontal_line): * redisplay-xlike-inc.c (XLIKE_output_eol_cursor): Update accordingly. * console-impl.h (struct console_methods): Add a background placement (Lisp_Object) argument to the clear_region method. * console-stream.c (stream_clear_region): * redisplay-tty.c (tty_clear_region): * redisplay-msw.c (mswindows_clear_region): * redisplay-xlike-inc.c (XLIKE_clear_region): Update accordingly. * redisplay-output.c (redisplay_clear_region): Handle the background placement property and update the call to the clear_region method. * faces.h (struct Lisp_Face): * faces.h (struct face_cachel): Add a background placement slot. * faces.h (WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT): New accessor. * faces.c (mark_face): * faces.c (face_equal): * faces.c (face_getprop): * faces.c (face_putprop): * faces.c (face_remprop): * faces.c (face_plist): * faces.c (reset_face): * faces.c (mark_face_cachels): * faces.c (update_face_cachel_data): * faces.c (merge_face_cachel_data): * faces.c (reset_face_cachel): * faces.c (Fmake_face): * faces.c (Fcopy_face): Handle the background placement property. * faces.c (syms_of_faces): * faces.c (vars_of_faces): * faces.c (complex_vars_of_faces): Update accordingly.
author Didier Verna <didier@lrde.epita.fr>
date Thu, 25 Feb 2010 16:19:01 +0100
parents aa4cae427255
children 37a17808de95 0ca81354c4c7 65f5d45edc87
files lisp/ChangeLog lisp/cl-macs.el lisp/cus-face.el lisp/faces.el lisp/frame.el lisp/objects.el man/ChangeLog man/xemacs/custom.texi src/ChangeLog src/console-gtk-impl.h src/console-impl.h src/console-stream.c src/console-x-impl.h src/console-xlike-inc.h src/event-Xt.c src/faces.c src/faces.h src/frame-x.c src/gtk-glue.c src/objects-impl.h src/objects.c src/objects.h src/redisplay-msw.c src/redisplay-output.c src/redisplay-tty.c src/redisplay-xlike-inc.c
diffstat 26 files changed, 619 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/ChangeLog	Thu Feb 25 16:19:01 2010 +0100
@@ -1,3 +1,21 @@
+2010-02-25  Didier Verna  <didier@xemacs.org>
+
+	The background-placement face property.
+	* cl-macs.el (face-background-placement): New defsetf.
+	* cus-face.el (custom-face-attributes):
+	* faces.el (face-interactive):
+	* faces.el (set-face-property):
+	* faces.el (face-equal):
+	* faces.el (init-other-random-faces): Update.
+	* faces.el (face-background-placement):
+	* faces.el (set-face-background-placement):
+	* faces.el (face-background-placement-instance):
+	* faces.el (face-background-placement-instance-p):
+	* frame.el (set-frame-background-placement):
+	* frame.el (frame-background-placement):
+	* frame.el (frame-background-placement-instance):
+	* objects.el (make-face-background-placement-specifier): New.
+
 c2010-02-25  Ben Wing  <ben@xemacs.org>
 
 	* autoload.el (make-autoload):
--- a/lisp/cl-macs.el	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/cl-macs.el	Thu Feb 25 16:19:01 2010 +0100
@@ -2159,6 +2159,8 @@
 (defsetf face-background (f &optional s) (x) (list 'set-face-background f x s))
 (defsetf face-background-pixmap (f &optional s) (x)
   (list 'set-face-background-pixmap f x s))
+(defsetf face-background-placement (f &optional s) (x)
+  (list 'set-face-background-placement f x s))
 (defsetf face-font (f &optional s) (x) (list 'set-face-font f x s))
 (defsetf face-foreground (f &optional s) (x) (list 'set-face-foreground f x s))
 (defsetf face-underline-p (f &optional s) (x)
--- a/lisp/cus-face.el	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/cus-face.el	Thu Feb 25 16:19:01 2010 +0100
@@ -1,6 +1,7 @@
 ;;; cus-face.el -- Support for Custom faces.
 ;;
 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 2010 Didier Verna
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Maintainer: Hrvoje Niksic <hniksic@xemacs.org>
@@ -83,7 +84,12 @@
 					:help-echo "\
 Name of background pixmap file.")
 	      set-face-background-pixmap custom-face-background-pixmap)
-    (:dim (toggle :format "%[Dim%]: %v\n"
+    (:background-placement (choice :tag "Background placement" :value relative
+				   (const :tag "Relative" :value relative)
+				   (const :tag "Absolute" :value absolute))
+			   set-face-background-placement
+			   face-background-placement) 
+   (:dim (toggle :format "%[Dim%]: %v\n"
 		  :help-echo "Control whether the text should be dimmed.")
 	  set-face-dim-p face-dim-p)
     (:bold (toggle :format "%[Bold%]: %v\n"
--- a/lisp/faces.el	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/faces.el	Thu Feb 25 16:19:01 2010 +0100
@@ -3,6 +3,7 @@
 ;; Copyright (C) 1992-4, 1997 Free Software Foundation, Inc.
 ;; Copyright (C) 1995 Board of Trustees, University of Illinois
 ;; Copyright (C) 1995, 1996, 2002, 2005 Ben Wing
+;; Copyright (C) 2010 Didier Verna
 
 ;; Author: Ben Wing <ben@xemacs.org>
 ;; Keywords: faces, internal, dumped
@@ -87,6 +88,8 @@
 			  (color-instance-name default))
 			 ((image-instance-p default)
 			  (image-instance-file-name default))
+			 ((face-background-placement-instance-p default)
+			  (symbol-name default))
 			 (t default))))))
     (list face (if (equal value "") nil value))))
 
@@ -333,6 +336,11 @@
                     Only used by faces on X and MS Windows devices.
                     For valid instantiators, see `make-image-specifier'.
 
+ background-placement  The placement of the face's background pixmap.
+                    Only used by faces on X devices.
+                    For valid instantiators,
+                    see `make-face-background-placement-specifier'.
+
  underline          Underline all text covered by this face.
                     For valid instantiators, see `make-face-boolean-specifier'.
 
@@ -716,6 +724,45 @@
      (list face (if (equal file "") nil file))))
   (set-face-property face 'background-pixmap file))
 
+(defun face-background-placement (face &optional domain default no-fallback)
+  "Return FACE's background placement in DOMAIN.
+See `face-property-instance' for the semantics of the DOMAIN argument."
+  (face-property face 'background-placement domain default no-fallback))
+
+(defun set-face-background-placement (face placement &optional locale tag-set
+				      how-to-add)
+  "Change the background-placement property of FACE to PLACEMENT.
+PLACEMENT is normally a background-placement instantiator; see
+`make-face-background-placement-specifier'.
+See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
+HOW-TO-ADD arguments."
+  (interactive (face-interactive "background placement"))
+  ;; When called non-interactively (for example via custom), PLACEMENT is
+  ;; expected to be a symbol. -- dvl
+  (unless (symbolp placement)
+    (setq placement (intern placement)))
+  (set-face-property face 'background-placement placement locale tag-set
+		     how-to-add))
+
+(defun face-background-placement-instance (face &optional domain default
+					   no-fallback)
+  "Return FACE's background-placement instance in DOMAIN.
+Return value will be a background-placement instance object.
+
+FACE may be either a face object or a symbol representing a face.
+
+Normally DOMAIN will be a window or nil (meaning the selected window),
+and an instance object describing the background placement in that particular
+window and buffer will be returned.
+
+See `face-property-instance' for more information."
+  (face-property-instance face 'background-placement domain default
+			  no-fallback))
+
+(defun face-background-placement-instance-p (object)
+  "Return t if OBJECT is a face-background-placement instance."
+  (or (eq object 'absolute) (eq object 'relative)))
+
 (defun face-display-table (face &optional locale tag-set exact-p)
   "Return the display table spec of FACE in LOCALE, or nil if unspecified..
 
@@ -871,7 +918,7 @@
   (let ((device (dfw-device domain))
 	(common-props '(foreground background font display-table underline
 				   dim inherit))
-	(win-props '(background-pixmap strikethru))
+	(win-props '(background-pixmap background-placement strikethru))
 	(tty-props '(highlight blinking reverse)))
 
     ;; First check the properties which are used in common between the
@@ -1943,7 +1990,8 @@
   ;; element faces. So take the modeline face information from its
   ;; fallbacks, themselves ultimately set up in faces.c:
   (loop
-    for face-property in '(foreground background background-pixmap)
+    for face-property in '(foreground background 
+			   background-pixmap background-placement)
     do (when (and (setq face-property (face-property 'modeline face-property))
                   (null (specifier-instance face-property device nil t))
                   (specifier-instance face-property device))
--- a/lisp/frame.el	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/frame.el	Thu Feb 25 16:19:01 2010 +0100
@@ -3,6 +3,7 @@
 ;; Copyright (C) 1993, 1994, 1996, 1997, 2000, 2001, 2003
 ;;   Free Software Foundation, Inc.
 ;; Copyright (C) 1995, 1996 Ben Wing.
+;; Copyright (C) 2010 Didier Verna
 
 ;; Maintainer: XEmacs Development Team
 ;; Keywords: internal, dumped
@@ -1015,6 +1016,28 @@
   "Set property PROP of FRAME to VAL.  See `set-frame-properties'."
   (set-frame-properties frame (list prop val)))
 
+(defun set-frame-background-placement (placement)
+  "Set the background placement of the selected frame to PLACEMENT.
+When called interactively, prompt for the placement to use."
+  (interactive (list (intern (completing-read "Placement: "
+					      '(("absolute" absolute)
+						("relative" relative))
+					      nil t))))
+  (set-face-background-placement 'default placement (selected-frame)))
+
+(defun frame-background-placement ()
+  "Retrieve the selected frame's background placement."
+  (interactive)
+  (face-background-placement 'default (selected-frame)))
+
+(defun frame-background-placement-instance ()
+  "Retrieve the selected frame's background placement instance."
+  (interactive)
+  (face-background-placement-instance 'default (selected-frame)))
+
+;; #### FIXME: misnomers ! The functions below should be called
+;; set-frame-<blabla> -- dvl.
+
 ;; XEmacs change: this function differs significantly from Emacs.
 (defun set-background-color (color-name)
   "Set the background color of the selected frame to COLOR-NAME.
--- a/lisp/objects.el	Thu Feb 25 06:14:50 2010 -0600
+++ b/lisp/objects.el	Thu Feb 25 16:19:01 2010 +0100
@@ -2,6 +2,7 @@
 
 ;; Copyright (C) 1994, 1997 Free Software Foundation, Inc.
 ;; Copyright (C) 1995 Ben Wing
+;; Copyright (C) 2010 Didier Verna
 
 ;; Author: Chuck Thompson <cthomp@xemacs.org>
 ;; Author: Ben Wing <ben@xemacs.org>
@@ -194,4 +195,18 @@
    if non-nil, means to invert the sense of the inherited property."
   (make-specifier-and-init 'face-boolean spec-list))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; face-background-placement specifiers
+
+(defun make-face-background-placement-specifier (spec-list)
+  "Return a new `face-background-placement' specifier object.
+SPEC-LIST can be a list of specifications (each of which is a cons of a
+locale and a list of instantiators), a single instantiator, or a list
+of instantiators.  See `make-specifier' for a detailed description of
+how specifiers work.
+
+Valid instantiators for face-background-placement specifiers are:
+-- absolute or relative (symbols),
+-- a vector of one element: a face to inherit from."
+  (make-specifier-and-init 'face-background-placement spec-list))
+
 ;;; objects.el ends here.
--- a/man/ChangeLog	Thu Feb 25 06:14:50 2010 -0600
+++ b/man/ChangeLog	Thu Feb 25 16:19:01 2010 +0100
@@ -1,3 +1,8 @@
+2010-02-25  Didier Verna  <didier@xemacs.org>
+
+	The background-placement face property.
+	* xemacs/custom.texi (Faces): Document it.
+
 2010-02-20  Ben Wing  <ben@xemacs.org>
 
 	* internals/internals.texi (Intro to Window and Frame Geometry):
--- a/man/xemacs/custom.texi	Thu Feb 25 06:14:50 2010 -0600
+++ b/man/xemacs/custom.texi	Thu Feb 25 16:19:01 2010 +0100
@@ -2080,6 +2080,8 @@
 Change the background pixmap of the given @var{face}.
 @item M-x set-face-background-pixmap-file
 A simpler version but with filename completion.
+@item M-x set-face-background-placement
+Change the placement of the background pixmap of the given @var{face}.
 @item M-x set-face-font
 Change the font of the given @var{face}.
 @item M-x set-face-foreground
@@ -2161,6 +2163,18 @@
 as much control on the pixmap instantiator, but provides filename
 completion.
 
+@findex set-face-background-placement
+You can set the placement of the background pixmap of the specified
+@var{face} with the function @code{set-face-background-placement}. The
+placement argument can be either @code{absolute} or @code{relative} (the
+default). A @code{relative} placement means that the pixmap is attached
+to the frame and moves with it. An @code{absolute} placement means that
+the pixmap is rather attached to the frame's root window, so that when
+you move the frame on the screen, it will appear to ``slide'' on the
+pixmap. This placement mode can be used to achieve pseudo-translucency
+for a frame, for example by setting the default face's background pixmap
+to the root window's one.
+
 @findex set-face-font
 You can set the font of the specified @var{face} with the function
 @code{set-face-font}.  The @var{font} argument should be a string, the
--- a/src/ChangeLog	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/ChangeLog	Thu Feb 25 16:19:01 2010 +0100
@@ -1,3 +1,70 @@
+2010-02-25  Didier Verna  <didier@xemacs.org>
+
+	The background-placement face property.
+	* console-x-impl.h (struct x_frame): Add new slots x and y.
+	* console-x-impl.h (FRAME_X_X, FRAME_X_Y): New slot accessors.
+	* console-gtk-impl.h: Fake something similar for potential port.
+	* frame-x.c (x_get_frame_text_position): New function.
+	* frame-x.c (x_init_frame_3): Use it.
+	* event-Xt.c (emacs_Xt_handle_magic_event): Eat spurious
+	ConfigureNotify events, get the frame position and mark frame
+	faces changed.
+	* objects-impl.h: The face_background_placement_specifier
+	structure and its accessors.
+	* objects.c: New symbols Qabsolute and Qrelative.
+	* objects.c (face_background_placement_create):
+	* objects.c (face_background_placement_mark):
+	* objects.c (face_background_placement_instantiate):
+	* objects.c (face_background_placement_validate):
+	* objects.c (face_background_placement_after_change):
+	* objects.c (set_face_background_placement_attached_to): New.
+	* objects.h (set_face_background_palcement_attached_to): Declare
+	the one above.
+	* objects.c (syms_of_objects):
+	* objects.c (specifier_type_create_objects):
+	* objects.c (reinit_specifier_type_create_objects):
+	* objects.c (reinit_vars_of_objects): Update for the modifications
+	above.
+	* console-xlike-inc.h (XLIKE_GC_TS_X_ORIGIN, XLIKE_GC_TS_X_ORIGIN): 
+	New X11/Gtk compatibility macros.
+	* redisplay-xlike-inc.c (XLIKE_get_gc): Add a background placement
+	argument and handle it.
+	* gtk-glue.c (face_to_gc):
+	* redisplay-xlike-inc.c (XLIKE_output_string):
+	* redisplay-xlike-inc.c (XLIKE_output_pixmap):
+	* redisplay-xlike-inc.c (XLIKE_output_blank):
+	* redisplay-xlike-inc.c (XLIKE_output_horizontal_line):
+	* redisplay-xlike-inc.c (XLIKE_output_eol_cursor): Update
+	accordingly.
+	* console-impl.h (struct console_methods): Add a background
+	placement (Lisp_Object) argument to the clear_region method.
+	* console-stream.c (stream_clear_region):
+	* redisplay-tty.c (tty_clear_region):
+	* redisplay-msw.c (mswindows_clear_region):
+	* redisplay-xlike-inc.c (XLIKE_clear_region): Update accordingly.
+	* redisplay-output.c (redisplay_clear_region): Handle the
+	background placement property and update the call to the
+	clear_region method.
+	* faces.h (struct Lisp_Face):
+	* faces.h (struct face_cachel): Add a background placement slot.
+	* faces.h (WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT): New accessor.
+	* faces.c (mark_face):
+	* faces.c (face_equal):
+	* faces.c (face_getprop):
+	* faces.c (face_putprop):
+	* faces.c (face_remprop):
+	* faces.c (face_plist):
+	* faces.c (reset_face):
+	* faces.c (mark_face_cachels):
+	* faces.c (update_face_cachel_data):
+	* faces.c (merge_face_cachel_data):
+	* faces.c (reset_face_cachel):
+	* faces.c (Fmake_face):
+	* faces.c (Fcopy_face): Handle the background placement property.
+	* faces.c (syms_of_faces):
+	* faces.c (vars_of_faces):
+	* faces.c (complex_vars_of_faces): Update accordingly.
+
 2010-02-25  Ben Wing  <ben@xemacs.org>
 
 	* frame-impl.h:
--- a/src/console-gtk-impl.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/console-gtk-impl.h	Thu Feb 25 16:19:01 2010 +0100
@@ -159,6 +159,11 @@
   /* The widget of the edit portion of this frame; this is a GtkDrawingArea,
      and the window of this widget is what the redisplay code draws on. */
   GtkWidget *edit_widget;
+  /* #### WARNING: this does not currently work. -- dvl
+     Position of the edit widget above, for absolute background placement.
+     
+     int x, y;
+  */
 
   /* Lists the widgets above the text area, in the proper order. */
   GtkWidget *top_widgets[MAX_CONCURRENT_TOP_WIDGETS];
@@ -213,6 +218,10 @@
 
 #define FRAME_GTK_DATA(f) FRAME_TYPE_DATA (f, gtk)
 
+/* #### WARNING: this does not currently work. -- dvl
+   #define FRAME_GTK_X(f) (FRAME_GTK_DATA (f)->x)
+   #define FRAME_GTK_Y(f) (FRAME_GTK_DATA (f)->y)
+*/
 #define FRAME_GTK_SHELL_WIDGET(f)	    (FRAME_GTK_DATA (f)->widget)
 #define FRAME_GTK_CONTAINER_WIDGET(f) (FRAME_GTK_DATA (f)->container)
 #define FRAME_GTK_MENUBAR_WIDGET(f)   (FRAME_GTK_DATA (f)->menubar_widget)
--- a/src/console-impl.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/console-impl.h	Thu Feb 25 16:19:01 2010 +0100
@@ -153,9 +153,10 @@
   int (*eol_cursor_width_method) (void);
   void (*output_vertical_divider_method) (struct window *, int);
   void (*clear_to_window_end_method) (struct window *, int, int);
-  void (*clear_region_method) (Lisp_Object, struct device*, struct frame*, face_index,
-			       int, int, int, int,
-			       Lisp_Object, Lisp_Object, Lisp_Object);
+  void (*clear_region_method) (Lisp_Object, struct device*, struct frame*,
+			       face_index, int, int, int, int,
+			       Lisp_Object, Lisp_Object,
+			       Lisp_Object, Lisp_Object);
   void (*clear_frame_method) (struct frame *);
   void (*window_output_begin_method) (struct window *);
   void (*frame_output_begin_method) (struct frame *);
--- a/src/console-stream.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/console-stream.c	Thu Feb 25 16:19:01 2010 +0100
@@ -282,7 +282,8 @@
 		     int UNUSED (x), int UNUSED (y), int UNUSED (width),
 		     int UNUSED (height), Lisp_Object UNUSED (fcolor),
 		     Lisp_Object UNUSED (bcolor),
-		     Lisp_Object UNUSED (background_pixmap))
+		     Lisp_Object UNUSED (background_pixmap),
+		     Lisp_Object UNUSED (background_placement))
 {
   ABORT ();
 }
--- a/src/console-x-impl.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/console-x-impl.h	Thu Feb 25 16:19:01 2010 +0100
@@ -2,6 +2,7 @@
    Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
    Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
    Copyright (C) 1996, 2002, 2003 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -265,6 +266,8 @@
   /* The widget of the edit portion of this frame; this is an EmacsFrame,
      and the window of this widget is what the redisplay code draws on. */
   Widget edit_widget;
+  /* Position of the edit widget above, for absolute background placement. */
+  int x, y;
 
   /* Lists the widgets above the text area, in the proper order.
      Used by the EmacsManager. */
@@ -360,6 +363,8 @@
 #endif /* NEW_GC */
 #define FRAME_X_DATA(f) FRAME_TYPE_DATA (f, x)
 
+#define FRAME_X_X(f) (FRAME_X_DATA (f)->x)
+#define FRAME_X_Y(f) (FRAME_X_DATA (f)->y)
 #define FRAME_X_SHELL_WIDGET(f)	    (FRAME_X_DATA (f)->widget)
 #define FRAME_X_CONTAINER_WIDGET(f) (FRAME_X_DATA (f)->container)
 #define FRAME_X_MENUBAR_WIDGET(f)   (FRAME_X_DATA (f)->menubar_widget)
@@ -407,6 +412,8 @@
 
 extern struct console_type *x_console_type;
 
+void x_get_frame_text_position (struct frame *);
+
 #endif /* HAVE_X_WINDOWS */
 
 #endif /* INCLUDED_console_x_impl_h_ */
--- a/src/console-xlike-inc.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/console-xlike-inc.h	Thu Feb 25 16:19:01 2010 +0100
@@ -169,6 +169,8 @@
 #define XLIKE_GC_LINE_WIDTH GCLineWidth
 #define XLIKE_GC_STIPPLE GCStipple
 #define XLIKE_GC_TILE GCTile
+#define XLIKE_GC_TS_X_ORIGIN GCTileStipXOrigin
+#define XLIKE_GC_TS_Y_ORIGIN GCTileStipYOrigin
 
 #define XLIKE_GX_COPY GXcopy
 #define XLIKE_GX_XOR GXxor
@@ -258,6 +260,8 @@
 #define XLIKE_GC_LINE_WIDTH GDK_GC_LINE_WIDTH
 #define XLIKE_GC_STIPPLE GDK_GC_STIPPLE
 #define XLIKE_GC_TILE GDK_GC_TILE
+#define XLIKE_GC_TS_X_ORIGIN GDK_GC_TS_X_ORIGIN
+#define XLIKE_GC_TS_Y_ORIGIN GDK_GC_TS_Y_ORIGIN
 
 #define XLIKE_GX_COPY GDK_COPY
 #define XLIKE_GX_XOR GDK_XOR
--- a/src/event-Xt.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/event-Xt.c	Thu Feb 25 16:19:01 2010 +0100
@@ -2,6 +2,7 @@
    Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
    Copyright (C) 1995 Sun Microsystems, Inc.
    Copyright (C) 1996, 2001, 2002, 2003, 2010 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -1898,6 +1899,25 @@
       break;
 
     case ConfigureNotify:
+      {
+	XEvent xev;
+	
+	/* Let's eat all events of that type to avoid useless
+	   reconfigurations. */
+	while (XCheckTypedWindowEvent
+	       (DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f))),
+		XtWindow (FRAME_X_TEXT_WIDGET (f)),
+		ConfigureNotify,
+		&xev)
+	       == True);
+      }
+      /* #### NOTE: in fact, the frame faces didn't really change, but if some
+	 #### of them have their background-placement property set to
+	 #### absolute, we need a redraw. This is semantically equivalent to
+	 #### changing the background pixmap. -- dvl */
+      x_get_frame_text_position (f);
+      MARK_FRAME_FACES_CHANGED (f);
+
 #ifdef HAVE_XIM
       XIM_SetGeometry (f);
 #endif
--- a/src/faces.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/faces.c	Thu Feb 25 16:19:01 2010 +0100
@@ -3,6 +3,7 @@
    Copyright (C) 1995 Board of Trustees, University of Illinois.
    Copyright (C) 1995, 1996, 2001, 2002, 2005, 2010 Ben Wing.
    Copyright (C) 1995 Sun Microsystems, Inc.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -42,7 +43,7 @@
 
 Lisp_Object Qfacep;
 Lisp_Object Qforeground, Qbackground, Qdisplay_table;
-Lisp_Object Qbackground_pixmap, Qunderline, Qdim;
+Lisp_Object Qbackground_pixmap, Qbackground_placement, Qunderline, Qdim;
 Lisp_Object Qblinking, Qstrikethru;
 
 Lisp_Object Qinit_face_from_resources;
@@ -111,6 +112,7 @@
   mark_object (face->font);
   mark_object (face->display_table);
   mark_object (face->background_pixmap);
+  mark_object (face->background_placement);
   mark_object (face->underline);
   mark_object (face->strikethru);
   mark_object (face->highlight);
@@ -162,6 +164,9 @@
      internal_equal (f1->font,		     f2->font,		    depth) &&
      internal_equal (f1->display_table,	     f2->display_table,	    depth) &&
      internal_equal (f1->background_pixmap,  f2->background_pixmap, depth) &&
+     internal_equal (f1->background_placement, 
+		     f2->background_placement,
+		     depth)                                                &&
      internal_equal (f1->underline,	     f2->underline,	    depth) &&
      internal_equal (f1->strikethru,	     f2->strikethru,	    depth) &&
      internal_equal (f1->highlight,	     f2->highlight,	    depth) &&
@@ -192,18 +197,19 @@
   Lisp_Face *f = XFACE (obj);
 
   return
-    (EQ (prop, Qforeground)	   ? f->foreground	  :
-     EQ (prop, Qbackground)	   ? f->background	  :
-     EQ (prop, Qfont)		   ? f->font		  :
-     EQ (prop, Qdisplay_table)	   ? f->display_table	  :
-     EQ (prop, Qbackground_pixmap) ? f->background_pixmap :
-     EQ (prop, Qunderline)	   ? f->underline	  :
-     EQ (prop, Qstrikethru)	   ? f->strikethru	  :
-     EQ (prop, Qhighlight)	   ? f->highlight	  :
-     EQ (prop, Qdim)		   ? f->dim		  :
-     EQ (prop, Qblinking)	   ? f->blinking	  :
-     EQ (prop, Qreverse)	   ? f->reverse		  :
-     EQ (prop, Qdoc_string)	   ? f->doc_string	  :
+    (EQ (prop, Qforeground)	      ? f->foreground           :
+     EQ (prop, Qbackground)	      ? f->background           :
+     EQ (prop, Qfont)		      ? f->font                 :
+     EQ (prop, Qdisplay_table)	      ? f->display_table        :
+     EQ (prop, Qbackground_pixmap)    ? f->background_pixmap    :
+     EQ (prop, Qbackground_placement) ? f->background_placement :
+     EQ (prop, Qunderline)	      ? f->underline            :
+     EQ (prop, Qstrikethru)	      ? f->strikethru           :
+     EQ (prop, Qhighlight)	      ? f->highlight            :
+     EQ (prop, Qdim)		      ? f->dim                  :
+     EQ (prop, Qblinking)	      ? f->blinking             :
+     EQ (prop, Qreverse)	      ? f->reverse              :
+     EQ (prop, Qdoc_string)	      ? f->doc_string           :
      external_plist_get (&f->plist, prop, 0, ERROR_ME));
 }
 
@@ -212,16 +218,17 @@
 {
   Lisp_Face *f = XFACE (obj);
 
-  if (EQ (prop, Qforeground)        ||
-      EQ (prop, Qbackground)        ||
-      EQ (prop, Qfont)              ||
-      EQ (prop, Qdisplay_table)     ||
-      EQ (prop, Qbackground_pixmap) ||
-      EQ (prop, Qunderline)         ||
-      EQ (prop, Qstrikethru)        ||
-      EQ (prop, Qhighlight)         ||
-      EQ (prop, Qdim)               ||
-      EQ (prop, Qblinking)          ||
+  if (EQ (prop, Qforeground)           ||
+      EQ (prop, Qbackground)           ||
+      EQ (prop, Qfont)                 ||
+      EQ (prop, Qdisplay_table)        ||
+      EQ (prop, Qbackground_pixmap)    ||
+      EQ (prop, Qbackground_placement) ||
+      EQ (prop, Qunderline)            ||
+      EQ (prop, Qstrikethru)           ||
+      EQ (prop, Qhighlight)            ||
+      EQ (prop, Qdim)                  ||
+      EQ (prop, Qblinking)             ||
       EQ (prop, Qreverse))
     return 0;
 
@@ -242,16 +249,17 @@
 {
   Lisp_Face *f = XFACE (obj);
 
-  if (EQ (prop, Qforeground)        ||
-      EQ (prop, Qbackground)        ||
-      EQ (prop, Qfont)              ||
-      EQ (prop, Qdisplay_table)     ||
-      EQ (prop, Qbackground_pixmap) ||
-      EQ (prop, Qunderline)         ||
-      EQ (prop, Qstrikethru)        ||
-      EQ (prop, Qhighlight)         ||
-      EQ (prop, Qdim)               ||
-      EQ (prop, Qblinking)          ||
+  if (EQ (prop, Qforeground)           ||
+      EQ (prop, Qbackground)           ||
+      EQ (prop, Qfont)                 ||
+      EQ (prop, Qdisplay_table)        ||
+      EQ (prop, Qbackground_pixmap)    ||
+      EQ (prop, Qbackground_placement) ||
+      EQ (prop, Qunderline)            ||
+      EQ (prop, Qstrikethru)           ||
+      EQ (prop, Qhighlight)            ||
+      EQ (prop, Qdim)                  ||
+      EQ (prop, Qblinking)             ||
       EQ (prop, Qreverse))
     return -1;
 
@@ -270,17 +278,18 @@
   Lisp_Face *face = XFACE (obj);
   Lisp_Object result = face->plist;
 
-  result = cons3 (Qreverse,	      face->reverse,	       result);
-  result = cons3 (Qblinking,	      face->blinking,	       result);
-  result = cons3 (Qdim,		      face->dim,	       result);
-  result = cons3 (Qhighlight,	      face->highlight,	       result);
-  result = cons3 (Qstrikethru,	      face->strikethru,	       result);
-  result = cons3 (Qunderline,	      face->underline,	       result);
-  result = cons3 (Qbackground_pixmap, face->background_pixmap, result);
-  result = cons3 (Qdisplay_table,     face->display_table,     result);
-  result = cons3 (Qfont,	      face->font,	       result);
-  result = cons3 (Qbackground,	      face->background,	       result);
-  result = cons3 (Qforeground,	      face->foreground,	       result);
+  result = cons3 (Qreverse,	         face->reverse,	               result);
+  result = cons3 (Qblinking,	         face->blinking,               result);
+  result = cons3 (Qdim,		         face->dim,	               result);
+  result = cons3 (Qhighlight,	         face->highlight,              result);
+  result = cons3 (Qstrikethru,	         face->strikethru,             result);
+  result = cons3 (Qunderline,	         face->underline,              result);
+  result = cons3 (Qbackground_placement, face->background_placement,   result);
+  result = cons3 (Qbackground_pixmap,    face->background_pixmap,      result);
+  result = cons3 (Qdisplay_table,        face->display_table,          result);
+  result = cons3 (Qfont,	         face->font,                   result);
+  result = cons3 (Qbackground,	         face->background,             result);
+  result = cons3 (Qforeground,	         face->foreground,             result);
 
   return result;
 }
@@ -293,6 +302,7 @@
   { XD_LISP_OBJECT, offsetof (Lisp_Face, font) },
   { XD_LISP_OBJECT, offsetof (Lisp_Face, display_table) },
   { XD_LISP_OBJECT, offsetof (Lisp_Face, background_pixmap) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Face, background_placement) },
   { XD_LISP_OBJECT, offsetof (Lisp_Face, underline) },
   { XD_LISP_OBJECT, offsetof (Lisp_Face, strikethru) },
   { XD_LISP_OBJECT, offsetof (Lisp_Face, highlight) },
@@ -386,6 +396,7 @@
   f->font = Qnil;
   f->display_table = Qnil;
   f->background_pixmap = Qnil;
+  f->background_placement = Qnil;
   f->underline = Qnil;
   f->strikethru = Qnil;
   f->highlight = Qnil;
@@ -845,6 +856,8 @@
   set_font_attached_to (f->font, face, Qfont);
   f->background_pixmap = Fmake_specifier (Qimage);
   set_image_attached_to (f->background_pixmap, face, Qbackground_pixmap);
+  f->background_placement = Fmake_specifier (Qface_background_placement);
+  set_face_background_placement_attached_to (f->background_placement, face);
   f->display_table = Fmake_specifier (Qdisplay_table);
   f->underline = Fmake_specifier (Qface_boolean);
   set_face_boolean_attached_to (f->underline, face, Qunderline);
@@ -873,6 +886,9 @@
       set_specifier_fallback (f->background_pixmap,
 			     Fget (Vdefault_face, Qbackground_pixmap,
 				   Qunbound));
+      set_specifier_fallback (f->background_placement,
+			      Fget (Vdefault_face, Qbackground_placement,
+				    Qunbound));
       set_specifier_fallback (f->display_table,
 			     Fget (Vdefault_face, Qdisplay_table, Qunbound));
       set_specifier_fallback (f->underline,
@@ -1067,6 +1083,7 @@
       mark_object (cachel->background);
       mark_object (cachel->display_table);
       mark_object (cachel->background_pixmap);
+      mark_object (cachel->background_placement);
     }
 }
 
@@ -1423,6 +1440,9 @@
 	  FROB (background_pixmap);
 	  MAYBE_UNFROB_BACKGROUND_PIXMAP;
 	}
+
+      FROB (background_placement);
+
 #undef FROB
 #undef MAYBE_UNFROB_BACKGROUND_PIXMAP
 
@@ -1486,6 +1506,7 @@
   FROB (background);
   FROB (display_table);
   FROB (background_pixmap);
+  FROB (background_placement);
   FROB (underline);
   FROB (strikethru);
   FROB (highlight);
@@ -1536,6 +1557,7 @@
   }
   cachel->display_table = Qunbound;
   cachel->background_pixmap = Qunbound;
+  cachel->background_placement = Qunbound;
   FACE_CACHEL_FONT_SPECIFIED (cachel)->size = sizeof(cachel->font_specified);
   FACE_CACHEL_FONT_UPDATED (cachel)->size = sizeof(cachel->font_updated);
 }
@@ -1901,8 +1923,8 @@
   /* If the locale could affect the frame value, then call
      update_EmacsFrames just in case. */
   if (default_face &&
-      (EQ (property, Qforeground) ||
-       EQ (property, Qbackground) ||
+      (EQ (property, Qforeground)           ||
+       EQ (property, Qbackground)           ||
        EQ (property, Qfont)))
     update_EmacsFrames (locale, property);
 
@@ -1996,6 +2018,7 @@
   COPY_PROPERTY (font);
   COPY_PROPERTY (display_table);
   COPY_PROPERTY (background_pixmap);
+  COPY_PROPERTY (background_placement);
   COPY_PROPERTY (underline);
   COPY_PROPERTY (strikethru);
   COPY_PROPERTY (highlight);
@@ -2126,6 +2149,7 @@
   /* Qfont defined in general.c */
   DEFSYMBOL (Qdisplay_table);
   DEFSYMBOL (Qbackground_pixmap);
+  DEFSYMBOL (Qbackground_placement);
   DEFSYMBOL (Qunderline);
   DEFSYMBOL (Qstrikethru);
   /* Qhighlight, Qreverse defined in general.c */
@@ -2199,6 +2223,7 @@
     syms[n++] = Qfont;
     syms[n++] = Qdisplay_table;
     syms[n++] = Qbackground_pixmap;
+    syms[n++] = Qbackground_placement;
     syms[n++] = Qunderline;
     syms[n++] = Qstrikethru;
     syms[n++] = Qhighlight;
@@ -2517,6 +2542,9 @@
   set_specifier_fallback (Fget (Vmodeline_face, Qbackground_pixmap, Qnil),
 			  Fget (Vgui_element_face, Qbackground_pixmap,
 				Qunbound));
+  set_specifier_fallback (Fget (Vmodeline_face, Qbackground_placement, Qnil),
+			  Fget (Vgui_element_face, Qbackground_placement,
+				Qunbound));
 
   /* toolbar is another gui element */
   Vtoolbar_face = Fmake_face (Qtoolbar,
@@ -2529,6 +2557,9 @@
   set_specifier_fallback (Fget (Vtoolbar_face, Qbackground_pixmap, Qnil),
 			  Fget (Vgui_element_face, Qbackground_pixmap,
 				Qunbound));
+  set_specifier_fallback (Fget (Vtoolbar_face, Qbackground_placement, Qnil),
+			  Fget (Vgui_element_face, Qbackground_placement,
+				Qunbound));
 
   /* vertical divider is another gui element */
   Vvertical_divider_face = Fmake_face (Qvertical_divider,
@@ -2543,6 +2574,10 @@
 				Qunbound),
 			  Fget (Vgui_element_face, Qbackground_pixmap,
 				Qunbound));
+  set_specifier_fallback (Fget (Vvertical_divider_face, Qbackground_placement,
+				Qnil),
+			  Fget (Vgui_element_face, Qbackground_placement,
+				Qunbound));
 
   /* widget is another gui element */
   Vwidget_face = Fmake_face (Qwidget,
--- a/src/faces.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/faces.h	Thu Feb 25 16:19:01 2010 +0100
@@ -1,6 +1,7 @@
 /* Face data structures.
    Copyright (C) 1995 Board of Trustees, University of Illinois.
    Copyright (C) 1995, 2002, 2010 Ben Wing
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -47,6 +48,7 @@
 
   Lisp_Object display_table;
   Lisp_Object background_pixmap;
+  Lisp_Object background_placement;
 
   Lisp_Object underline;
   Lisp_Object strikethru;
@@ -172,6 +174,7 @@
 
   Lisp_Object display_table;
   Lisp_Object background_pixmap;
+  Lisp_Object background_placement;
 
   unsigned int underline :1;
   unsigned int strikethru :1;
@@ -188,6 +191,7 @@
   unsigned int background_specified :1;
   unsigned int display_table_specified :1;
   unsigned int background_pixmap_specified :1;
+  unsigned int background_placement_specified :1;
 
   unsigned int strikethru_specified :1;
   unsigned int underline_specified :1;
@@ -340,6 +344,8 @@
   (WINDOW_FACE_CACHEL (window, index)->display_table)
 #define WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP(window, index)		\
   (WINDOW_FACE_CACHEL (window, index)->background_pixmap)
+#define WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT(window, index)		\
+  (WINDOW_FACE_CACHEL (window, index)->background_placement)
 #define WINDOW_FACE_CACHEL_DIRTY(window, index)				\
   (WINDOW_FACE_CACHEL (window, index)->dirty)
 #define WINDOW_FACE_CACHEL_UNDERLINE_P(window, index)			\
@@ -396,6 +402,11 @@
   FACE_PROPERTY_INSTANCE (face, Qdisplay_table, domain, 0, Qzero)
 #define FACE_BACKGROUND_PIXMAP(face, domain)				\
   FACE_PROPERTY_INSTANCE (face, Qbackground_pixmap, domain, 0, Qzero)
+
+extern Lisp_Object Qbackground_placement;
+#define FACE_BACKGROUND_PLACEMENT(face, domain)				\
+  FACE_PROPERTY_INSTANCE (face, Qbackground_placement, domain, 0, Qzero)
+
 #define FACE_UNDERLINE_P(face, domain)					\
   (!NILP (FACE_PROPERTY_INSTANCE (face, Qunderline, domain, 0, Qzero)))
 #define FACE_STRIKETHRU_P(face, domain)					\
--- a/src/frame-x.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/frame-x.c	Thu Feb 25 16:19:01 2010 +0100
@@ -1,6 +1,7 @@
 /* Functions for the X window system.
    Copyright (C) 1989, 1992-5, 1997 Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 2001, 2002, 2004, 2010 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -537,6 +538,23 @@
   *y = xwa.y;
 }
 
+void x_get_frame_text_position (struct frame *f)
+{
+  Display *dpy = DEVICE_X_DISPLAY (XDEVICE (FRAME_DEVICE (f)));
+  Window window = XtWindow (FRAME_X_TEXT_WIDGET (f));
+  Window root, child;
+  int x, y;
+  unsigned int width, height, border_width;
+  unsigned int depth;
+
+  XGetGeometry (dpy, window, &root, &x, &y, &width, &height, &border_width,
+		&depth);
+  XTranslateCoordinates (dpy, window, root, 0, 0, &x, &y, &child);
+
+  FRAME_X_X (f) = x;
+  FRAME_X_Y (f) = y;
+}
+
 #if 0
 static void
 x_smash_bastardly_shell_position (Widget shell)
@@ -2119,9 +2137,13 @@
 static void
 x_init_frame_3 (struct frame *f)
 {
-  /* Pop up the frame. */
-
+  /* #### NOTE: This whole business of splitting frame initialization into
+     #### different functions is somewhat messy. The latest one seems a good
+     #### place to initialize the edit widget's position because we're sure
+     #### that the frame is now relalized. -- dvl */
+  
   x_popup_frame (f);
+  x_get_frame_text_position (f);
 }
 
 static void
--- a/src/gtk-glue.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/gtk-glue.c	Thu Feb 25 16:19:01 2010 +0100
@@ -220,6 +220,9 @@
 		      Fspecifier_instance (Fget (face, Qbackground_pixmap,
 						 Qnil),
 					   frame, Qnil, Qnil),
+		      Fspecifier_instance (Fget (face, Qbackground_placement,
+						 Qnil),
+					   frame, Qnil, Qnil),
 		      Qnil));
 }
 
--- a/src/objects-impl.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/objects-impl.h	Thu Feb 25 16:19:01 2010 +0100
@@ -1,6 +1,7 @@
 /* Generic object functions -- header implementation.
    Copyright (C) 1995 Board of Trustees, University of Illinois.
    Copyright (C) 1995, 1996, 2002 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -93,6 +94,31 @@
 #define CONCHECK_FACE_BOOLEAN_SPECIFIER(x) \
   CONCHECK_SPECIFIER_TYPE (x, face_boolean)
 
+/*****************************************************************************
+ *                  Background Placement Specifier Object                    *
+ *****************************************************************************/
+
+struct face_background_placement_specifier
+{
+  Lisp_Object face;		/* face this is attached to, or nil */
+};
+
+#define FACE_BACKGROUND_PLACEMENT_SPECIFIER_DATA(g)	\
+  SPECIFIER_TYPE_DATA (g, face_background_placement)
+#define FACE_BACKGROUND_PLACEMENT_SPECIFIER_FACE(g)	\
+  (FACE_BACKGROUND_PLACEMENT_SPECIFIER_DATA (g)->face)
+
+DECLARE_SPECIFIER_TYPE (face_background_placement);
+extern Lisp_Object Qface_background_placement, Qabsolute, Qrelative;
+#define XFACE_BACKGROUND_PLACEMENT_SPECIFIER(x)		\
+  XSPECIFIER_TYPE (x, face_background_placement)
+#define FACE_BACKGROUND_PLACEMENT_SPECIFIERP(x)		\
+  SPECIFIER_TYPEP (x, face_background_placement)
+#define CHECK_FACE_BACKGROUND_PLACEMENT_SPECIFIER(x)	\
+  CHECK_SPECIFIER_TYPE (x, face_background_placement)
+#define CONCHECK_FACE_BACKGROUND_PLACEMENT_SPECIFIER(x)		\
+  CONCHECK_SPECIFIER_TYPE (x, face_background_placement)
+
 /****************************************************************************
  *                           Color Instance Object                          *
  ****************************************************************************/
--- a/src/objects.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/objects.c	Thu Feb 25 16:19:01 2010 +0100
@@ -2,6 +2,7 @@
    Copyright (C) 1995 Free Software Foundation, Inc.
    Copyright (C) 1995 Board of Trustees, University of Illinois.
    Copyright (C) 1995, 1996, 2002, 2004, 2005, 2010 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -1212,6 +1213,130 @@
 }
 
 
+/*****************************************************************************
+ Face Background Placement Object
+ ****************************************************************************/
+Lisp_Object Qabsolute, Qrelative;
+
+static const struct memory_description
+face_background_placement_specifier_description[] = {
+  { XD_LISP_OBJECT, offsetof (struct face_background_placement_specifier,
+			      face) },
+  { XD_END }
+};
+
+DEFINE_SPECIFIER_TYPE_WITH_DATA (face_background_placement);
+Lisp_Object Qface_background_placement;
+
+static void
+face_background_placement_create (Lisp_Object obj)
+{
+  Lisp_Specifier *face_background_placement
+    = XFACE_BACKGROUND_PLACEMENT_SPECIFIER (obj);
+
+  FACE_BACKGROUND_PLACEMENT_SPECIFIER_FACE (face_background_placement) = Qnil;
+}
+
+static void
+face_background_placement_mark (Lisp_Object obj)
+{
+  Lisp_Specifier *face_background_placement
+    = XFACE_BACKGROUND_PLACEMENT_SPECIFIER (obj);
+
+  mark_object
+    (FACE_BACKGROUND_PLACEMENT_SPECIFIER_FACE (face_background_placement));
+}
+
+/* No equal or hash methods; ignore the face the background-placement is based
+   off of for `equal' */
+
+extern Lisp_Object Qbackground_placement;
+
+static Lisp_Object
+face_background_placement_instantiate (Lisp_Object UNUSED (specifier),
+				       Lisp_Object UNUSED (matchspec),
+				       Lisp_Object domain,
+				       Lisp_Object instantiator,
+				       Lisp_Object depth,
+				       int no_fallback)
+{
+  /* When called, we're inside of call_with_suspended_errors(),
+     so we can freely error. */
+  if (EQ (instantiator, Qabsolute) || EQ (instantiator, Qrelative))
+    return instantiator;
+  else if (VECTORP (instantiator))
+    {
+      assert (XVECTOR_LENGTH (instantiator) == 1);
+
+      return FACE_PROPERTY_INSTANCE_1
+	(Fget_face (XVECTOR_DATA (instantiator)[0]),
+	 Qbackground_placement, domain, ERROR_ME, no_fallback, depth);
+    }
+  else
+    ABORT ();	/* Eh? */
+
+  return Qunbound;
+}
+
+static void
+face_background_placement_validate (Lisp_Object instantiator)
+{
+  if (EQ (instantiator, Qabsolute) || EQ (instantiator, Qrelative))
+    return;
+  else if (VECTORP (instantiator) &&
+	   (XVECTOR_LENGTH (instantiator) == 1))
+    {
+      Lisp_Object face = XVECTOR_DATA (instantiator)[0];
+
+      Fget_face (face); /* just to check that the face exists -- dvl */
+    }
+  else if (VECTORP (instantiator))
+    sferror ("Wrong length for background-placement inheritance spec",
+	     instantiator);
+  else
+    invalid_argument
+      ("\
+Background-placement instantiator must be absolute, relative or vector",
+       instantiator);
+}
+
+static void
+face_background_placement_after_change (Lisp_Object specifier,
+					Lisp_Object locale)
+{
+  Lisp_Object face
+    = FACE_BACKGROUND_PLACEMENT_SPECIFIER_FACE
+    (XFACE_BACKGROUND_PLACEMENT_SPECIFIER (specifier));
+
+  if (!NILP (face))
+    {
+      face_property_was_changed (face, Qbackground_placement, locale);
+      if (BUFFERP (locale))
+	XBUFFER (locale)->buffer_local_face_property = 1;
+    }
+}
+
+void
+set_face_background_placement_attached_to (Lisp_Object obj, Lisp_Object face)
+{
+  Lisp_Specifier *face_background_placement
+    = XFACE_BACKGROUND_PLACEMENT_SPECIFIER (obj);
+
+  FACE_BACKGROUND_PLACEMENT_SPECIFIER_FACE (face_background_placement) = face;
+}
+
+DEFUN ("face-background-placement-specifier-p", Fface_background_placement_specifier_p, 1, 1, 0, /*
+Return non-nil if OBJECT is a face-background-placement specifier.
+
+See `make-face-background-placement-specifier' for a description of possible
+face-background-placement instantiators.
+*/
+       (object))
+{
+  return FACE_BACKGROUND_PLACEMENT_SPECIFIERP (object) ? Qt : Qnil;
+}
+
+
 /************************************************************************/
 /*                            initialization                            */
 /************************************************************************/
@@ -1225,6 +1350,7 @@
   DEFSUBR (Fcolor_specifier_p);
   DEFSUBR (Ffont_specifier_p);
   DEFSUBR (Fface_boolean_specifier_p);
+  DEFSUBR (Fface_background_placement_specifier_p);
 
   DEFSYMBOL_MULTIWORD_PREDICATE (Qcolor_instancep);
   DEFSUBR (Fmake_color_instance);
@@ -1249,6 +1375,10 @@
 
   /* Qcolor, Qfont defined in general.c */
   DEFSYMBOL (Qface_boolean);
+
+  DEFSYMBOL (Qface_background_placement);
+  DEFSYMBOL (Qabsolute);
+  DEFSYMBOL (Qrelative);
 }
 
 void
@@ -1258,26 +1388,35 @@
   INITIALIZE_SPECIFIER_TYPE_WITH_DATA (font, "font", "font-specifier-p");
   INITIALIZE_SPECIFIER_TYPE_WITH_DATA (face_boolean, "face-boolean",
 					 "face-boolean-specifier-p");
+  INITIALIZE_SPECIFIER_TYPE_WITH_DATA (face_background_placement,
+				       "face-background-placement",
+				       "\
+face-background-placement-specifier-p");
 
   SPECIFIER_HAS_METHOD (color, instantiate);
   SPECIFIER_HAS_METHOD (font, instantiate);
   SPECIFIER_HAS_METHOD (face_boolean, instantiate);
+  SPECIFIER_HAS_METHOD (face_background_placement, instantiate);
 
   SPECIFIER_HAS_METHOD (color, validate);
   SPECIFIER_HAS_METHOD (font, validate);
   SPECIFIER_HAS_METHOD (face_boolean, validate);
+  SPECIFIER_HAS_METHOD (face_background_placement, validate);
 
   SPECIFIER_HAS_METHOD (color, create);
   SPECIFIER_HAS_METHOD (font, create);
   SPECIFIER_HAS_METHOD (face_boolean, create);
+  SPECIFIER_HAS_METHOD (face_background_placement, create);
 
   SPECIFIER_HAS_METHOD (color, mark);
   SPECIFIER_HAS_METHOD (font, mark);
   SPECIFIER_HAS_METHOD (face_boolean, mark);
+  SPECIFIER_HAS_METHOD (face_background_placement, mark);
 
   SPECIFIER_HAS_METHOD (color, after_change);
   SPECIFIER_HAS_METHOD (font, after_change);
   SPECIFIER_HAS_METHOD (face_boolean, after_change);
+  SPECIFIER_HAS_METHOD (face_background_placement, after_change);
 
 #ifdef MULE
   SPECIFIER_HAS_METHOD (font, validate_matchspec);
@@ -1290,6 +1429,7 @@
   REINITIALIZE_SPECIFIER_TYPE (color);
   REINITIALIZE_SPECIFIER_TYPE (font);
   REINITIALIZE_SPECIFIER_TYPE (face_boolean);
+  REINITIALIZE_SPECIFIER_TYPE (face_background_placement);
 }
 
 void
--- a/src/objects.h	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/objects.h	Thu Feb 25 16:19:01 2010 +0100
@@ -76,4 +76,12 @@
 void set_face_boolean_attached_to (Lisp_Object obj, Lisp_Object face,
 				   Lisp_Object property);
 
+/*****************************************************************************
+ *              Face Background Placement Specifier Object                   *
+ *****************************************************************************/
+
+void set_face_background_placement_attached_to
+(Lisp_Object obj, Lisp_Object face);
+
+
 #endif /* INCLUDED_objects_h_ */
--- a/src/redisplay-msw.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/redisplay-msw.c	Thu Feb 25 16:19:01 2010 +0100
@@ -1212,8 +1212,13 @@
 			struct device *UNUSED (d), struct frame *f, 
 			face_index UNUSED (findex), int x, int y,
 			int width, int height, Lisp_Object fcolor,
-			Lisp_Object bcolor, Lisp_Object background_pixmap)
+			Lisp_Object bcolor,
+			Lisp_Object background_pixmap,
+			Lisp_Object background_placement)
 {
+  /* #### FIXME: don't know how to handle background_placement in mswindows.
+     -- dvl */
+
   RECT rect = { x, y, x+width, y+height };
   HDC hdc = get_frame_dc (f, 1);
 
--- a/src/redisplay-output.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/redisplay-output.c	Thu Feb 25 16:19:01 2010 +0100
@@ -3,6 +3,7 @@
    Copyright (C) 1995, 1996, 2002, 2003 Ben Wing.
    Copyright (C) 1996 Chuck Thompson.
    Copyright (C) 1999, 2002 Andy Piper.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -1721,6 +1722,7 @@
   struct frame *f = NULL;
   struct device *d;
   Lisp_Object background_pixmap = Qunbound;
+  Lisp_Object background_placement = Qunbound;
   Lisp_Object fcolor = Qnil, bcolor = Qnil;
 
   if (!width || !height)
@@ -1765,22 +1767,26 @@
 	      /* #### maybe we could implement such that a string
 		 can be a background pixmap? */
 	      background_pixmap = temp;
+	      background_placement
+		= WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, findex);
 	    }
 	}
       else
 	{
 	  temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale);
-
+	  
 	  if (IMAGE_INSTANCEP (temp)
 	      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
 	    {
 	      background_pixmap = temp;
+	      background_placement
+		= FACE_BACKGROUND_PLACEMENT (Vdefault_face, locale);
 	    }
 	}
     }
 
-  if (!UNBOUNDP (background_pixmap) &&
-      XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0)
+  if (!UNBOUNDP (background_pixmap)
+      && XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0)
     {
       if (w)
 	{
@@ -1805,7 +1811,8 @@
     background_pixmap = Qnil;
 
   DEVMETH (d, clear_region, (locale, d, f, findex, x, y, width, height,
-			     fcolor, bcolor, background_pixmap));
+			     fcolor, bcolor, 
+			     background_pixmap, background_placement));
 }
 
 /****************************************************************************
--- a/src/redisplay-tty.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/redisplay-tty.c	Thu Feb 25 16:19:01 2010 +0100
@@ -428,7 +428,8 @@
 		  struct frame * f, face_index findex, int x, int y,
 		  int width, int height, Lisp_Object UNUSED (fcolor),
 		  Lisp_Object UNUSED (bcolor),
-		  Lisp_Object UNUSED (background_pixmap))
+		  Lisp_Object UNUSED (background_pixmap),
+		  Lisp_Object UNUSED (background_placement))
 {
   struct console *c = XCONSOLE (FRAME_CONSOLE (f));
   int line;
--- a/src/redisplay-xlike-inc.c	Thu Feb 25 06:14:50 2010 -0600
+++ b/src/redisplay-xlike-inc.c	Thu Feb 25 16:19:01 2010 +0100
@@ -3,6 +3,7 @@
    Copyright (C) 1994 Lucid, Inc.
    Copyright (C) 1995 Sun Microsystems, Inc.
    Copyright (C) 2002, 2003, 2005, 2009, 2010 Ben Wing.
+   Copyright (C) 2010 Didier Verna
 
 This file is part of XEmacs.
 
@@ -812,8 +813,9 @@
 
 /* Called as gtk_get_gc from gtk-glue.c */
 
-XLIKE_GC XLIKE_get_gc (struct frame *f, Lisp_Object font, Lisp_Object fg, 
-		       Lisp_Object bg, Lisp_Object bg_pmap,
+XLIKE_GC XLIKE_get_gc (struct frame *f, Lisp_Object font,
+		       Lisp_Object fg, Lisp_Object bg,
+		       Lisp_Object bg_pixmap, Lisp_Object bg_placement,
 		       Lisp_Object lwidth);
 
 /*****************************************************************************
@@ -822,8 +824,10 @@
  Given a number of parameters return a GC with those properties.
  ****************************************************************************/
 XLIKE_GC
-XLIKE_get_gc (struct frame *f, Lisp_Object font, Lisp_Object fg, 
-	      Lisp_Object bg, Lisp_Object bg_pmap, Lisp_Object lwidth)
+XLIKE_get_gc (struct frame *f, Lisp_Object font, 
+	      Lisp_Object fg, Lisp_Object bg,
+	      Lisp_Object bg_pixmap, Lisp_Object bg_placement, 
+	      Lisp_Object lwidth)
 {
   struct device *d = XDEVICE (f->device);
   XLIKE_GCVALUES gcv;
@@ -837,7 +841,8 @@
   gcv.clip_x_origin = 0;
   gcv.clip_y_origin = 0;
   XLIKE_SET_GC_FILL (gcv, XLIKE_FILL_SOLID);
-  mask = XLIKE_GC_EXPOSURES | XLIKE_GC_CLIP_MASK | XLIKE_GC_CLIP_X_ORIGIN | XLIKE_GC_CLIP_Y_ORIGIN;
+  mask = XLIKE_GC_EXPOSURES
+    | XLIKE_GC_CLIP_MASK | XLIKE_GC_CLIP_X_ORIGIN | XLIKE_GC_CLIP_Y_ORIGIN;
   mask |= XLIKE_GC_FILL;
 
   if (!NILP (font)
@@ -883,7 +888,7 @@
 
   /* This special case comes from a request to draw text with a face which has
      the dim property. We'll use a stippled foreground GC. */
-  if (EQ (bg_pmap, Qdim))
+  if (EQ (bg_pixmap, Qdim))
     {
       assert (DEVICE_XLIKE_GRAY_PIXMAP (d) != XLIKE_NONE);
 
@@ -891,21 +896,35 @@
       gcv.stipple = DEVICE_XLIKE_GRAY_PIXMAP (d);
       mask |= (XLIKE_GC_FILL | XLIKE_GC_STIPPLE);
     }
-  else if (IMAGE_INSTANCEP (bg_pmap)
-	   && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
+  else if (IMAGE_INSTANCEP (bg_pixmap)
+	   && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pixmap)))
     {
-      if (XIMAGE_INSTANCE_PIXMAP_DEPTH (bg_pmap) == 0)
+      if (XIMAGE_INSTANCE_PIXMAP_DEPTH (bg_pixmap) == 0)
 	{
 	  XLIKE_SET_GC_FILL (gcv, XLIKE_FILL_OPAQUE_STIPPLED);
-	  gcv.stipple = XIMAGE_INSTANCE_XLIKE_PIXMAP (bg_pmap);
+	  gcv.stipple = XIMAGE_INSTANCE_XLIKE_PIXMAP (bg_pixmap);
 	  mask |= (XLIKE_GC_STIPPLE | XLIKE_GC_FILL);
 	}
       else
 	{
 	  XLIKE_SET_GC_FILL (gcv, XLIKE_FILL_TILED);
-	  gcv.tile = XIMAGE_INSTANCE_XLIKE_PIXMAP (bg_pmap);
+	  gcv.tile = XIMAGE_INSTANCE_XLIKE_PIXMAP (bg_pixmap);
 	  mask |= (XLIKE_GC_TILE | XLIKE_GC_FILL);
 	}
+      if (EQ (bg_placement, Qabsolute))
+	{
+#ifdef THIS_IS_GTK
+	  /* #### WARNING: this does not currently work. -- dvl
+	     gcv.ts_x_origin = - FRAME_GTK_X (f);
+	     gcv.ts_y_origin = - FRAME_GTK_Y (f);
+	     mask |= (XLIKE_GC_TS_X_ORIGIN | XLIKE_GC_TS_Y_ORIGIN);
+	  */
+#else
+	  gcv.ts_x_origin = - FRAME_X_X (f);
+	  gcv.ts_y_origin = - FRAME_X_Y (f);
+	  mask |= (XLIKE_GC_TS_X_ORIGIN | XLIKE_GC_TS_Y_ORIGIN);
+#endif
+	}
     }
 
   if (!NILP (lwidth))
@@ -1078,7 +1097,7 @@
     bgc = 0;
   else
     bgc = XLIKE_get_gc (f, Qnil, cachel->foreground, cachel->background,
-			bg_pmap, Qnil);
+			bg_pmap, cachel->background_placement, Qnil);
 
   if (bgc)
     {
@@ -1159,7 +1178,7 @@
 	  bg = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0);
 #endif
 	  gc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
-			     cursor_cachel->background, Qnil, Qnil);
+			     cursor_cachel->background, Qnil, Qnil, Qnil);
 	}
       else if (cachel->dim)
 	{
@@ -1181,7 +1200,7 @@
 	  bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
 #endif
 	  gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
-			     Qdim, Qnil);
+			     Qdim, Qnil, Qnil);
 	}
       else
 	{
@@ -1190,7 +1209,7 @@
 	  bg = XFT_FROB_LISP_COLOR (cachel->background, 0);
 #endif
 	  gc = XLIKE_get_gc (f, font, cachel->foreground, cachel->background,
-			     Qnil, Qnil);
+			     Qnil, Qnil, Qnil);
 	}
 #ifdef USE_XFT
       {
@@ -1464,7 +1483,7 @@
 	      XLIKE_RECTANGLE clip_box;
 	      XLIKE_GC cgc;
 	      cgc = XLIKE_get_gc (f, font, cursor_cachel->foreground,
-				  cursor_cachel->background, Qnil, Qnil);
+				  cursor_cachel->background, Qnil, Qnil, Qnil);
 
 	      clip_box.x = 0;
 	      clip_box.y = 0;
@@ -1535,13 +1554,14 @@
 
       if (!NILP (bar_cursor_value))
 	{
-	  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil,
+	  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
+			     Qnil, Qnil,
 			     make_int (bar_width));
 	}
       else
 	{
 	  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background,
-			     Qnil, Qnil, Qnil);
+			     Qnil, Qnil, Qnil, Qnil);
 	}
 
       tmp_y = dl->ypos - bogusly_obtained_ascent_value;
@@ -1729,7 +1749,8 @@
 			    get_builtin_face_cache_index
 			    (w, Vtext_cursor_face));
 
-      gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil);
+      gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil,
+			 Qnil);
 
       if (cursor_width > db->xpos + dga->width - cursor_start)
 	cursor_width = db->xpos + dga->width - cursor_start;
@@ -1874,10 +1895,12 @@
 
   if (NILP (bg_pmap))
     gc = XLIKE_get_gc (f, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, rb->findex),
-		       Qnil, Qnil, Qnil);
+		       Qnil, Qnil, Qnil, Qnil);
   else
     gc = XLIKE_get_gc (f, Qnil, WINDOW_FACE_CACHEL_FOREGROUND (w, rb->findex),
-		       WINDOW_FACE_CACHEL_BACKGROUND (w, rb->findex), bg_pmap,
+		       WINDOW_FACE_CACHEL_BACKGROUND (w, rb->findex),
+		       bg_pmap,
+		       WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, rb->findex),
 		       Qnil);
 
   XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, y, width, height);
@@ -1898,7 +1921,8 @@
 			   (WINDOW_FACE_CACHEL (w, rb->findex),
 			    Vcharset_ascii));
 
-      gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil);
+      gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
+			 Qnil, Qnil, Qnil);
 
       cursor_y = dl->ypos - fi->ascent;
       cursor_height = fi->height;
@@ -1917,7 +1941,8 @@
 	      int bar_width = EQ (bar_cursor_value, Qt) ? 1 : 2;
 
 	      gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background,
-				 Qnil, Qnil, make_int (bar_width));
+				 Qnil, Qnil, Qnil,
+				 make_int (bar_width));
 	      XLIKE_DRAW_LINE (dpy, x_win, gc, cursor_start + bar_width - 1,
 			       cursor_y, cursor_start + bar_width - 1,
 			       cursor_y + cursor_height - 1);
@@ -1962,7 +1987,7 @@
     {
       gc = XLIKE_get_gc (f, Qnil,
 			 WINDOW_FACE_CACHEL_FOREGROUND (w, rb->findex),
-			 Qnil, Qnil, Qnil);
+			 Qnil, Qnil, Qnil, Qnil);
 
       if (ypos2 - ypos1 > 0)
 	XLIKE_FILL_RECTANGLE (dpy, x_win, gc, x, ypos1, width, ypos2 - ypos1);
@@ -1979,7 +2004,7 @@
 #else /* THIS_IS_X */
   /* Now draw the line. */
   gc = XLIKE_get_gc (f, Qnil, WINDOW_FACE_CACHEL_BACKGROUND (w, rb->findex),
-		     Qnil, Qnil, Qnil);
+		     Qnil, Qnil, Qnil, Qnil);
 
   if (ypos2 < ypos1)
     ypos2 = ypos1;
@@ -2000,8 +2025,10 @@
 static void
 XLIKE_clear_region (Lisp_Object UNUSED (locale), struct device* d,
 		    struct frame* f, face_index UNUSED (findex), int x, int y,
-		    int width, int height, Lisp_Object fcolor,
-		    Lisp_Object bcolor, Lisp_Object background_pixmap)
+		    int width, int height,
+		    Lisp_Object fcolor, Lisp_Object bcolor,
+		    Lisp_Object background_pixmap,
+		    Lisp_Object background_placement)
 {
   XLIKE_DISPLAY dpy = GET_XLIKE_DISPLAY (d);
   XLIKE_WINDOW x_win = GET_XLIKE_WINDOW (f);
@@ -2009,7 +2036,8 @@
 
   if (!UNBOUNDP (background_pixmap))
     {
-      gc = XLIKE_get_gc (f, Qnil, fcolor, bcolor, background_pixmap, Qnil);
+      gc = XLIKE_get_gc (f, Qnil, fcolor, bcolor,
+			 background_pixmap, background_placement, Qnil);
     }
 
   if (gc)
@@ -2055,7 +2083,8 @@
   if (NILP (w->text_cursor_visible_p))
     return;
 
-  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil);
+  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
+		     Qnil, Qnil, Qnil);
 
   default_face_font_info (window, &defascent, 0, 0, &defheight, 0);
 
@@ -2079,7 +2108,8 @@
 	{
 	  int bar_width = EQ (bar_cursor_value, Qt) ? 1 : 2;
 
-	  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil, Qnil,
+	  gc = XLIKE_get_gc (f, Qnil, cursor_cachel->background, Qnil,
+			     Qnil, Qnil,
 			     make_int (bar_width));
 	  XLIKE_DRAW_LINE (dpy, x_win, gc, x + bar_width - 1, cursor_y,
 			   x + bar_width - 1, cursor_y + cursor_height - 1);