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.