[comp.windows.x] xsetroot enhancements

ctr@xpiinc.UUCP (Christian Reimer, ctr@xpiinc.uu.net) (03/18/89)

  Many of the poskbitmaps are too small to cover the screen, yet too large
to be used as a tile for the root window.  Still others are larger than
my screen, in which case the image is clipped on the right and bottom edges.

  What I would rather see is the centering of these images on the screen;
small bitmaps appear in the center of the screen with a solid frame around
them, while large bitmaps would be clipped on all sides, so that the center
of the image is in the center of the screen.

  Included below are modifications to xsetroot which allow this behavior.
The new options are:

      -center
	  Center the bitmap on the screen.  This makes the  back-
          ground  a  single  copy of the bitmap, rather than many
          tiled images.   If  the  bitmap  is  smaller  than  the
          screen,  it is padded with the frame color (see below).
          If it is larger, it is clipped on all  sides,  so  that
          the center of the image is in the middle of the screen.

      -frame <color>
          This option specifies the color used  to  pad  centered
          bitmaps.   The  special  color GRAY (or GREY) is recog-
          nized (a la -gray).

  I don't have a color display to test this on, but it behaves correctly
on a monochrome display.  I'd like to hear from someone who tries it in
color, just to confirm that it works...

--------------------------------------
          Christian Reimer
   Visual Technology (XPI Division)
ctr@xpiinc.uu.net   | uunet!xpiinc!ctr

============================================================================
    xsetroot.c and xsetroot.man diffs, suitable for "patch"ing...
============================================================================
*** /tmp/,RCSt1a07644	Fri Mar 17 10:44:25 1989
--- xsetroot.c	Fri Mar 17 10:42:32 1989
***************
*** 30,35
  int reverse = 0;
  int save_colors = 0;
  int unsave_past = 0;
  Pixmap save_pixmap = (Pixmap)None;
  
  usage()

--- 30,37 -----
  int reverse = 0;
  int save_colors = 0;
  int unsave_past = 0;
+ int center_bitmap = 0;
+ char *frame_color = NULL;
  Pixmap save_pixmap = (Pixmap)None;
  
  usage()
***************
*** 48,53
      fprintf(stderr, "  -solid <color>\n");
      fprintf(stderr, "  -gray   or   -grey\n");
      fprintf(stderr, "  -bitmap <filename>\n");
      fprintf(stderr, "  -mod <x> <y>\n");
      exit(1);
      /*NOTREACHED*/

--- 50,57 -----
      fprintf(stderr, "  -solid <color>\n");
      fprintf(stderr, "  -gray   or   -grey\n");
      fprintf(stderr, "  -bitmap <filename>\n");
+     fprintf(stderr, "  -center\n");
+     fprintf(stderr, "  -frame <color>\n");
      fprintf(stderr, "  -mod <x> <y>\n");
      exit(1);
      /*NOTREACHED*/
***************
*** 135,140
  	    excl++;
  	    continue;
  	}
  	if (!strcmp("-mod", argv[i])) {
  	    if (++i>=argc) usage();
  	    mod_x = atoi(argv[i]);

--- 139,153 -----
  	    excl++;
  	    continue;
  	}
+ 	if( !strcmp("-center", argv[i])) {
+ 	    center_bitmap = 1;
+ 	    continue;
+ 	}
+ 	if( !strcmp("-frame", argv[i])) {
+ 	    if( ++i >= argc )  usage();
+ 	    frame_color = argv[i];
+ 	    continue;
+ 	}
  	if (!strcmp("-mod", argv[i])) {
  	    if (++i>=argc) usage();
  	    mod_x = atoi(argv[i]);
***************
*** 305,311
  	gc_init.background=temp;
      }
      gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
!     pix = XCreatePixmap(dpy, root, width, height,
  			(unsigned int)DefaultDepth(dpy, screen));
      XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
      XSetWindowBackgroundPixmap(dpy, root, pix);

--- 318,333 -----
  	gc_init.background=temp;
      }
      gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
! 
!     if( center_bitmap )
!     {
! 	unsigned int	w = DisplayWidth(dpy, screen),
! 			h = DisplayHeight(dpy, screen);
! 	GC		tmpgc;
! 	XGCValues	vals;
! 	unsigned long	vmask = GCForeground|GCBackground;
! 
! 	pix = XCreatePixmap(dpy, root, w, h,
  			(unsigned int)DefaultDepth(dpy, screen));
  
  	if( frame_color )
***************
*** 307,313
      gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
      pix = XCreatePixmap(dpy, root, width, height,
  			(unsigned int)DefaultDepth(dpy, screen));
!     XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
      XSetWindowBackgroundPixmap(dpy, root, pix);
      XFreeGC(dpy, gc);
      XFreePixmap(dpy, bitmap);

--- 329,372 -----
  
  	pix = XCreatePixmap(dpy, root, w, h,
  			(unsigned int)DefaultDepth(dpy, screen));
! 
! 	if( frame_color )
! 	{
! 	    vals.background = gc_init.background;
! 
! 	    if( !strcmp(frame_color, "GRAY") || !strcmp(frame_color, "GREY") )
! 	    {
! 		vals.foreground = gc_init.foreground;
! 		vals.fill_style = FillTiled;
! 		vals.tile = XCreatePixmapFromBitmapData(dpy, root,
! 				gray_bits, gray_width, gray_height,
! 				vals.foreground, vals.background,
! 				(unsigned int)DefaultDepth(dpy, screen));
! 		vmask |= GCFillStyle|GCTile;
! 	    }
! 	    else
! 	    {
! 		vals.foreground = NameToPixel(frame_color,
! 						BlackPixel(dpy, screen));
! 	    }
! 	}
! 	else
! 	{
! 	    vals.foreground = gc_init.foreground;
! 	    vals.background = gc_init.background;
! 	}
! 
! 	tmpgc = XCreateGC(dpy, pix, vmask, &vals);
! 	XFillRectangle(dpy, pix, tmpgc, 0, 0, w, h);
! 	CenterBitmap(gc, bitmap, width, height, &pix, w, h);
!     }
!     else
!     {
! 	pix = XCreatePixmap(dpy, root, width, height,
! 			(unsigned int)DefaultDepth(dpy, screen));
! 	XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height,
! 			0, 0, (unsigned long)1);
!     }
      XSetWindowBackgroundPixmap(dpy, root, pix);
      XFreeGC(dpy, gc);
      XFreePixmap(dpy, bitmap);
***************
*** 319,324
      unsave_past = 1;
  }
  
  
  /*
   * CreateCursorFromFiles: make a cursor of the right colors from two bitmap

--- 378,399 -----
      unsave_past = 1;
  }
  
+ /*
+  *   Puts Bitmap "bitmap" into the Pixmap pointed to by "ppix".  The bitmap
+  * image is cropped and/or centered within the Pixmap.
+  */
+ CenterBitmap(gc, bitmap, bw, bh, ppix, pw, ph)
+     GC			gc;
+     Pixmap		bitmap;
+     unsigned int	bw, bh;
+     Pixmap		*ppix;
+     unsigned int	pw, ph;
+ {
+     int			dw, dh,
+ 			srcx, srcy,
+ 			destx, desty;
+     unsigned int	w, h;
+     unsigned long	planes = 1;
  
      dw = pw - bw;
      if( dw > 0 )		/* thinner */
***************
*** 320,325
  }
  
  
  /*
   * CreateCursorFromFiles: make a cursor of the right colors from two bitmap
   *                        files.

--- 395,443 -----
      unsigned int	w, h;
      unsigned long	planes = 1;
  
+     dw = pw - bw;
+     if( dw > 0 )		/* thinner */
+     {
+ 	srcx = 0;
+ 	destx = dw/2;
+ 	w = bw;
+     }
+     else if( dw < 0 )		/* wider */
+     {
+ 	srcx = -dw/2;
+ 	destx = 0;
+ 	w = pw;
+     }
+     else			/* just right */
+     {
+ 	srcx = 0;
+ 	destx = 0;
+ 	w = bw;
+     }
+ 
+     dh = ph - bh;
+     if( dh > 0 )		/* shorter */
+     {
+ 	srcy = 0;
+ 	desty = dh/2;
+ 	h = bh;
+     }
+     else if( dh < 0 )		/* taller */
+     {
+ 	srcy = -dh/2;
+ 	desty = 0;
+ 	h = ph;
+     }
+     else			/* just right */
+     {
+ 	srcy = 0;
+ 	desty = 0;
+ 	h = bh;
+     }
+ 
+     XCopyPlane(dpy, bitmap, *ppix, gc, srcx, srcy, w, h, destx, desty, planes);
+ }
+ 
  /*
   * CreateCursorFromFiles: make a cursor of the right colors from two bitmap
   *                        files.
*** /tmp/,RCSt1a08156	Fri Mar 17 13:09:11 1989
--- xsetroot.man	Fri Mar 17 13:06:33 1989
***************
*** 5,10
  .B xsetroot
  [-help] [-def] [-display \fIdisplay\fP]
  [-cursor \fIcursorfile maskfile\fP] [-bitmap \fIfilename\fP]
  [-mod \fIx y\fP] [-gray] [-grey] [-fg \fIcolor\fP] [-bg \fIcolor\fP] [-rv]
  [-solid \fIcolor\fP] [-name \fIstring\fP]
  .SH DESCRIPTION

--- 5,11 -----
  .B xsetroot
  [-help] [-def] [-display \fIdisplay\fP]
  [-cursor \fIcursorfile maskfile\fP] [-bitmap \fIfilename\fP]
+ [-center] [-frame \fIcolor\fP]
  [-mod \fIx y\fP] [-gray] [-grey] [-fg \fIcolor\fP] [-bg \fIcolor\fP] [-rv]
  [-solid \fIcolor\fP] [-name \fIstring\fP]
  .SH DESCRIPTION
***************
*** 53,58
  .I bitmap(1)
  program.  The entire background will be made up of repeated "tiles" of
  the bitmap.
  .IP "\fB-mod\fP \fIx\fP \fIy\fP"
  This is used if you want a plaid-like grid pattern on your screen.
  x and y are integers ranging from 1 to 16.  Try the different combinations.

--- 54,68 -----
  .I bitmap(1)
  program.  The entire background will be made up of repeated "tiles" of
  the bitmap.
+ .IP \fB-center\fP
+ Center the bitmap on the screen.  This makes the background a single copy
+ of the bitmap, rather than many tiled images.  If the bitmap is smaller than
+ the screen, it is padded with the frame color (see below).  If it is larger,
+ it is clipped on all sides, so that the center of the image is in the middle
+ of the screen.
+ .IP "\fB-frame\fP \fIcolor\fP"
+ This option specifies the color used to pad centered bitmaps.  The special
+ color \fBGRAY\fP (or \fBGREY\fP) is recognized (a la \fB-gray\fP, below).
  .IP "\fB-mod\fP \fIx\fP \fIy\fP"
  This is used if you want a plaid-like grid pattern on your screen.
  x and y are integers ranging from 1 to 16.  Try the different combinations.