/* * xvroot.c - '-root' related code for XV * * Contains: * MakeRootPic() * ClearRoot() * SaveRootInfo() * KillOldRootInfo() */ #include "copyright.h" #include "xv.h" #include "bits/root_weave" /* local function pre-definitions */ static void killRootPix PARM((void)); /***********************************/ void MakeRootPic() { /* called after 'epic' has been generated (if we're using root). creates the XImage and the pixmap, sets the root to the new pixmap, and refreshes the display */ Pixmap tmpPix; int i, j, k, rmode; unsigned int rpixw, rpixh; killRootPix(); rmode = rootMode; /* if eWIDE,eHIGH == dispWIDE,dispHIGH just use 'normal' mode to save mem */ if (rmode>=RM_CENTER && eWIDE==dispWIDE && eHIGH==dispHIGH) rmode=RM_NORMAL; /* determine how big tmpPix should be based on rootMode */ switch (rmode) { case RM_NORMAL: case RM_CENTILE: case RM_TILE: rpixw = eWIDE; rpixh = eHIGH; break; case RM_MIRROR: case RM_IMIRROR: rpixw = 2*eWIDE; rpixh = 2*eHIGH; break; case RM_CSOLID: case RM_CWARP: case RM_CBRICK: rpixw = dispWIDE; rpixh = dispHIGH; break; case RM_ECENTER: case RM_ECMIRR: rpixw = dispWIDE; rpixh = dispHIGH; break; default: rpixw = eWIDE; rpixh = eHIGH; break; } if (nolimits) { RANGE(rpixw, 1, maxWIDE); RANGE(rpixh, 1, maxHIGH); } else { RANGE(rpixw, 1, dispWIDE); RANGE(rpixh, 1, dispHIGH); } /* create tmpPix */ xerrcode = 0; tmpPix = XCreatePixmap(theDisp, mainW, rpixw, rpixh, dispDEEP); XSync(theDisp, False); if (xerrcode || !tmpPix) { ErrPopUp("Insufficient memory in X server to store root pixmap.", "\nDarn!"); return; } if (rmode == RM_NORMAL || rmode == RM_TILE) { XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, (u_int) eWIDE, (u_int) eHIGH); } else if (rmode == RM_MIRROR || rmode == RM_IMIRROR) { /* quadrant 2 */ XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, (u_int) eWIDE, (u_int) eHIGH); if (epic == NULL) FatalError("epic == NULL in RM_MIRROR code...\n"); /* quadrant 1 */ FlipPic(epic, eWIDE, eHIGH, 0); /* flip horizontally */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,0, (u_int) eWIDE, (u_int) eHIGH); /* quadrant 4 */ FlipPic(epic, eWIDE, eHIGH, 1); /* flip vertically */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,eHIGH, (u_int) eWIDE, (u_int) eHIGH); /* quadrant 3 */ FlipPic(epic, eWIDE, eHIGH, 0); /* flip horizontally */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,eHIGH, (u_int) eWIDE, (u_int) eHIGH); FlipPic(epic, eWIDE, eHIGH, 1); /* flip vertically (back to orig) */ CreateXImage(); /* put back to original state */ } else if (rmode == RM_CENTER || rmode == RM_CENTILE || rmode == RM_CSOLID || rmode == RM_CWARP || rmode == RM_CBRICK) { /* do some stuff to set up the border around the picture */ if (rmode != RM_CENTILE) { XSetForeground(theDisp, theGC, rootbg); XFillRectangle(theDisp, tmpPix, theGC, 0,0, dispWIDE, dispHIGH); } if (rmode == RM_CENTILE) { /* hagan-style tiling */ int x, y, w, h, ax, ay, w1, h1, offx, offy; w = eWIDE; h = eHIGH; /* compute anchor pt (top-left coords of top-left-most pic) */ ax = (dispWIDE-w)/2; ay = (dispHIGH-h)/2; while (ax>0) ax = ax - w; while (ay>0) ay = ay - h; for (i=ay; i < (int) eHIGH; i+=h) { for (j=ax; j < (int) eWIDE; j+=w) { /* if image goes off tmpPix, only draw subimage */ x = j; y = i; w1 = w; h1 = h; offx = offy = 0; if (x<0) { offx = -x; w1 -= offx; x = 0; } if (x+w1>eWIDE) { w1 = (eWIDE-x); } if (y<0) { offy = -y; h1 -= offy; y = 0; } if (y+h1>eHIGH) { h1 = (eHIGH-y); } XPutImage(theDisp, tmpPix, theGC, theImage, offx, offy, x, y, (u_int) w1, (u_int) h1); } } } else if (rmode == RM_CSOLID) { } else if (rmode == RM_CWARP) { /* warp effect */ XSetForeground(theDisp, theGC, rootfg); for (i=0; i<=dispWIDE; i+=8) XDrawLine(theDisp,tmpPix,theGC, i,0, (int) dispWIDE-i,(int) dispHIGH); for (i=0; i<=dispHIGH; i+=8) XDrawLine(theDisp,tmpPix,theGC, 0,i, (int) dispWIDE, (int) dispHIGH-i); } else if (rmode == RM_CBRICK) { /* brick effect */ XSetForeground(theDisp, theGC, rootfg); for (i=k=0; iclass & 1)) return; /* no colormap to worry about */ if (riPix) return; /* it's already been saved once */ riPix = XCreatePixmap(theDisp, vrootW, 1, 1, 1); if (!riPix) return; /* unable to save. thankfully, unlikely to happen */ prop = XInternAtom(theDisp, "_XSETROOT_ID", False); if (!prop) FatalError("couldn't create _XSETROOT_ID atom"); XChangeProperty(theDisp, vrootW, prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &riPix, 1); XSetCloseDownMode(theDisp, RetainPermanent); } /***********************************/ void KillOldRootInfo() { /* get the pixmap ID from the _XSETROOT_ID property, and kill it */ Atom prop, type; int format; unsigned long length, after; unsigned char *data; prop = XInternAtom(theDisp, "_XSETROOT_ID", True); if (prop == None) return; /* no old pixmap to kill */ if (XGetWindowProperty(theDisp, vrootW, prop, 0L, 1L, True, AnyPropertyType, &type, &format, &length, &after, &data) == Success) { if (type==XA_PIXMAP && format==32 && length==1 && after==0 && data) { XKillClient(theDisp, *((Pixmap *)data)); XDeleteProperty(theDisp, vrootW, prop); } if (data) XFree((char *) data); } }