--- rxvt-unicode/src/xpm.C 2004/01/31 00:20:21 1.5 +++ rxvt-unicode/src/xpm.C 2004/02/01 01:34:41 1.7 @@ -1,7 +1,7 @@ /*--------------------------------*-C-*---------------------------------* * File: xpm.c *----------------------------------------------------------------------* - * $Id: xpm.C,v 1.5 2004/01/31 00:20:21 pcg Exp $ + * $Id: xpm.C,v 1.7 2004/02/01 01:34:41 pcg Exp $ * * All portions of code are copyright by their respective author/s. * Copyright (c) 1997 Carsten Haitzler @@ -52,306 +52,344 @@ int rxvt_term::scale_pixmap (const char *geom) { - int flags, changed = 0; - int x = 0, y = 0; - unsigned int w = 0, h = 0; - unsigned int n; - char *p, *str; - bgPixmap_t *bgpixmap = &(bgPixmap); + int flags, changed = 0; + int x = 0, y = 0; + unsigned int w = 0, h = 0; + unsigned int n; + char *p, *str; + bgPixmap_t *bgpixmap = &(bgPixmap); #define MAXLEN_GEOM sizeof("[1000x1000+1000+1000]") - if (geom == NULL) - return 0; - str = (char *)rxvt_malloc (MAXLEN_GEOM + 1); - if (!STRCMP(geom, "?")) { - sprintf(str, "[%dx%d+%d+%d]", /* can't presume snprintf() ! */ - min(bgpixmap->w, 9999), min(bgpixmap->h, 9999), - min(bgpixmap->x, 9999), min(bgpixmap->y, 9999)); - xterm_seq (XTerm_title, str, CHAR_ST); - free(str); - return 0; + if (geom == NULL) + return 0; + str = (char *)rxvt_malloc (MAXLEN_GEOM + 1); + if (!STRCMP(geom, "?")) + { + sprintf(str, "[%dx%d+%d+%d]", /* can't presume snprintf() ! */ + min(bgpixmap->w, 9999), min(bgpixmap->h, 9999), + min(bgpixmap->x, 9999), min(bgpixmap->y, 9999)); + xterm_seq (XTerm_title, str, CHAR_ST); + free(str); + return 0; } - if ((p = STRCHR(geom, ';')) == NULL) - p = STRCHR(geom, '\0'); - n = (p - geom); - if (n <= MAXLEN_GEOM) { - STRNCPY(str, geom, n); - str[n] = '\0'; - - flags = XParseGeometry(str, &x, &y, &w, &h); - if (!flags) { - flags |= WidthValue; - w = 0; - } /* default is tile */ - if (flags & WidthValue) { - if (!(flags & XValue)) - x = 50; - if (!(flags & HeightValue)) - h = w; - if (w && !h) { - w = (bgpixmap->w * w) / 100; - h = bgpixmap->h; - } else if (h && !w) { - w = bgpixmap->w; - h = (bgpixmap->h * h) / 100; - } - if (w > 1000) - w = 1000; - if (h > 1000) - h = 1000; - if (bgpixmap->w != (short)w) { - bgpixmap->w = (short)w; - changed++; - } - if (bgpixmap->h != (short)h) { - bgpixmap->h = (short)h; - changed++; - } - } - if (!(flags & YValue)) { - if (flags & XNegative) - flags |= YNegative; - y = x; - } - - if (!(flags & WidthValue) && geom[0] != '=') { - x += bgpixmap->x; - y += bgpixmap->y; - } else { - if (flags & XNegative) - x += 100; - if (flags & YNegative) - y += 100; - } - MIN_IT(x, 100); - MIN_IT(y, 100); - MAX_IT(x, 0); - MAX_IT(y, 0); - if (bgpixmap->x != x) { - bgpixmap->x = x; - changed++; - } - if (bgpixmap->y != y) { - bgpixmap->y = y; - changed++; - } + if ((p = STRCHR(geom, ';')) == NULL) + p = STRCHR(geom, '\0'); + n = (p - geom); + if (n <= MAXLEN_GEOM) + { + STRNCPY(str, geom, n); + str[n] = '\0'; + + flags = XParseGeometry(str, &x, &y, &w, &h); + if (!flags) + { + flags |= WidthValue; + w = 0; + } /* default is tile */ + if (flags & WidthValue) + { + if (!(flags & XValue)) + x = 50; + if (!(flags & HeightValue)) + h = w; + if (w && !h) + { + w = (bgpixmap->w * w) / 100; + h = bgpixmap->h; + } + else if (h && !w) + { + w = bgpixmap->w; + h = (bgpixmap->h * h) / 100; + } + if (w > 1000) + w = 1000; + if (h > 1000) + h = 1000; + if (bgpixmap->w != (short)w) + { + bgpixmap->w = (short)w; + changed++; + } + if (bgpixmap->h != (short)h) + { + bgpixmap->h = (short)h; + changed++; + } + } + if (!(flags & YValue)) + { + if (flags & XNegative) + flags |= YNegative; + y = x; + } + + if (!(flags & WidthValue) && geom[0] != '=') + { + x += bgpixmap->x; + y += bgpixmap->y; + } + else + { + if (flags & XNegative) + x += 100; + if (flags & YNegative) + y += 100; + } + MIN_IT(x, 100); + MIN_IT(y, 100); + MAX_IT(x, 0); + MAX_IT(y, 0); + if (bgpixmap->x != x) + { + bgpixmap->x = x; + changed++; + } + if (bgpixmap->y != y) + { + bgpixmap->y = y; + changed++; + } } - free(str); - return changed; + free(str); + return changed; } void rxvt_term::resize_pixmap () { - XGCValues gcvalue; - GC gc; - unsigned int width = TermWin_TotalWidth(); - unsigned int height = TermWin_TotalHeight(); - - if (TermWin.pixmap != None) - XFreePixmap(Xdisplay, TermWin.pixmap); - - if (bgPixmap.pixmap == None) { /* So be it: I'm not using pixmaps */ - TermWin.pixmap = None; - if (!(Options & Opt_transparent) || am_transparent == 0) - XSetWindowBackground(Xdisplay, TermWin.vt, - PixColors[Color_bg]); - return; + XGCValues gcvalue; + GC gc; + unsigned int width = TermWin_TotalWidth(); + unsigned int height = TermWin_TotalHeight(); + + if (TermWin.pixmap != None) + XFreePixmap(Xdisplay, TermWin.pixmap); + + if (bgPixmap.pixmap == None) + { /* So be it: I'm not using pixmaps */ + TermWin.pixmap = None; + if (!(Options & Opt_transparent) || am_transparent == 0) + XSetWindowBackground(Xdisplay, TermWin.vt, + PixColors[Color_bg]); + return; } - gcvalue.foreground = PixColors[Color_bg]; - gc = XCreateGC(Xdisplay, TermWin.vt, GCForeground, &gcvalue); + gcvalue.foreground = PixColors[Color_bg]; + gc = XCreateGC(Xdisplay, TermWin.vt, GCForeground, &gcvalue); - if (bgPixmap.pixmap != None) { /* we have a specified pixmap */ - unsigned int w = bgPixmap.w, h = bgPixmap.h, - x = bgPixmap.x, y = bgPixmap.y; - unsigned int xpmh = xpmAttr.height, - xpmw = xpmAttr.width; - - /* - * don't zoom pixmap too much nor expand really small pixmaps - */ - if (w > 1000 || h > 1000) - w = 1; - else if (width > (10 * xpmw) - || height > (10 * xpmh)) - w = 0; /* tile */ - - if (w == 0) { - /* basic X tiling - let the X server do it */ - TermWin.pixmap = XCreatePixmap(Xdisplay, TermWin.vt, - xpmw, xpmh, - (unsigned int)XDEPTH); - XCopyArea(Xdisplay, bgPixmap.pixmap, TermWin.pixmap, gc, - 0, 0, xpmw, xpmh, 0, 0); - } else { - float incr, p; - Pixmap tmp; - - TermWin.pixmap = XCreatePixmap(Xdisplay, TermWin.vt, - width, height, - (unsigned int)XDEPTH); - /* - * horizontal scaling - */ - rxvt_pixmap_incr(&w, &x, &incr, &p, width, xpmw); - - tmp = XCreatePixmap(Xdisplay, TermWin.vt, - width, xpmh, (unsigned int)XDEPTH); - XFillRectangle(Xdisplay, tmp, gc, 0, 0, width, - xpmh); - - for ( /*nil */ ; x < w; x++, p += incr) { - if (p >= xpmw) - p = 0; - /* copy one column from the original pixmap to the tmp pixmap */ - XCopyArea(Xdisplay, bgPixmap.pixmap, tmp, gc, - (int)p, 0, 1, xpmh, (int)x, 0); - } - - /* - * vertical scaling - */ - rxvt_pixmap_incr(&h, &y, &incr, &p, height, xpmh); - - if (y > 0) - XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, 0, width, - y); - if (h < height) - XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, (int)h, - width, height - h + 1); - for ( /*nil */ ; y < h; y++, p += incr) { - if (p >= xpmh) - p = 0; - /* copy one row from the tmp pixmap to the main pixmap */ - XCopyArea(Xdisplay, tmp, TermWin.pixmap, gc, - 0, (int)p, width, 1, 0, (int)y); - } - XFreePixmap(Xdisplay, tmp); - } + if (bgPixmap.pixmap != None) + { /* we have a specified pixmap */ + unsigned int w = bgPixmap.w, h = bgPixmap.h, + x = bgPixmap.x, y = bgPixmap.y; + unsigned int xpmh = xpmAttr.height, + xpmw = xpmAttr.width; + + /* + * don't zoom pixmap too much nor expand really small pixmaps + */ + if (w > 1000 || h > 1000) + w = 1; + else if (width > (10 * xpmw) + || height > (10 * xpmh)) + w = 0; /* tile */ + + if (w == 0) + { + /* basic X tiling - let the X server do it */ + TermWin.pixmap = XCreatePixmap(Xdisplay, TermWin.vt, + xpmw, xpmh, + (unsigned int)XDEPTH); + XCopyArea(Xdisplay, bgPixmap.pixmap, TermWin.pixmap, gc, + 0, 0, xpmw, xpmh, 0, 0); + } + else + { + float incr, p; + Pixmap tmp; + + TermWin.pixmap = XCreatePixmap(Xdisplay, TermWin.vt, + width, height, + (unsigned int)XDEPTH); + /* + * horizontal scaling + */ + rxvt_pixmap_incr(&w, &x, &incr, &p, width, xpmw); + + tmp = XCreatePixmap(Xdisplay, TermWin.vt, + width, xpmh, (unsigned int)XDEPTH); + XFillRectangle(Xdisplay, tmp, gc, 0, 0, width, + xpmh); + + for ( /*nil */ ; x < w; x++, p += incr) + { + if (p >= xpmw) + p = 0; + /* copy one column from the original pixmap to the tmp pixmap */ + XCopyArea(Xdisplay, bgPixmap.pixmap, tmp, gc, + (int)p, 0, 1, xpmh, (int)x, 0); + } + + /* + * vertical scaling + */ + rxvt_pixmap_incr(&h, &y, &incr, &p, height, xpmh); + + if (y > 0) + XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, 0, width, + y); + if (h < height) + XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, (int)h, + width, height - h + 1); + for ( /*nil */ ; y < h; y++, p += incr) + { + if (p >= xpmh) + p = 0; + /* copy one row from the tmp pixmap to the main pixmap */ + XCopyArea(Xdisplay, tmp, TermWin.pixmap, gc, + 0, (int)p, width, 1, 0, (int)y); + } + XFreePixmap(Xdisplay, tmp); + } } - XSetWindowBackgroundPixmap(Xdisplay, TermWin.vt, TermWin.pixmap); - XFreeGC(Xdisplay, gc); - am_transparent = 0; + XSetWindowBackgroundPixmap(Xdisplay, TermWin.vt, TermWin.pixmap); + XFreeGC(Xdisplay, gc); + am_transparent = 0; - XClearWindow(Xdisplay, TermWin.vt); + XClearWindow(Xdisplay, TermWin.vt); - XSync(Xdisplay, False); + XSync(Xdisplay, False); } /* * Calculate tiling sizes and increments * At start, p == 0, incr == xpmwidthheight */ -void +/* INTPROTO */ +static void rxvt_pixmap_incr(unsigned int *wh, unsigned int *xy, float *incr, float *p, unsigned int widthheight, unsigned int xpmwidthheight) { - unsigned int cwh, cxy; - float cincr, cp; + unsigned int cwh, cxy; + float cincr, cp; - cp = 0; - cincr = (float)xpmwidthheight; - cxy = *xy; - cwh = *wh; - if (cwh == 1) { /* display one image, no horizontal/vertical scaling */ - cincr = (float)widthheight; - if (xpmwidthheight <= widthheight) { - cwh = xpmwidthheight; - cxy = (cxy * (widthheight - cwh)) / 100; /* beware! order */ - cwh += cxy; - } else { - cxy = 0; - cwh = widthheight; - } - } else if (cwh < 10) { /* fit WH images across/down screen */ - cincr *= cwh; - cxy = 0; - cwh = widthheight; - } else { - cincr *= 100.0 / cwh; - if (cwh < 100) { /* contract */ - float pos; - - cwh = (cwh * widthheight) / 100; - pos = (float)cxy / 100 * widthheight - (cwh / 2); - - cxy = (widthheight - cwh); - if (pos <= 0) - cxy = 0; - else if (pos < cxy) - cxy = (int) pos; - cwh += cxy; - } else { /* expand */ - if (cxy > 0) { /* position */ - float pos; - - pos = (float)cxy / 100 * xpmwidthheight - (cincr / 2); - cp = xpmwidthheight - cincr; - if (pos <= 0) - cp = 0; - else if (pos < cp) - cp = pos; - } - cxy = 0; - cwh = widthheight; - } + cp = 0; + cincr = (float)xpmwidthheight; + cxy = *xy; + cwh = *wh; + if (cwh == 1) + { /* display one image, no horizontal/vertical scaling */ + cincr = (float)widthheight; + if (xpmwidthheight <= widthheight) + { + cwh = xpmwidthheight; + cxy = (cxy * (widthheight - cwh)) / 100; /* beware! order */ + cwh += cxy; + } + else + { + cxy = 0; + cwh = widthheight; + } + } + else if (cwh < 10) + { /* fit WH images across/down screen */ + cincr *= cwh; + cxy = 0; + cwh = widthheight; } - cincr /= widthheight; - *wh = cwh; - *xy = cxy; - *incr = cincr; - *p = cp; + else + { + cincr *= 100.0 / cwh; + if (cwh < 100) + { /* contract */ + float pos; + + cwh = (cwh * widthheight) / 100; + pos = (float)cxy / 100 * widthheight - (cwh / 2); + + cxy = (widthheight - cwh); + if (pos <= 0) + cxy = 0; + else if (pos < cxy) + cxy = (int) pos; + cwh += cxy; + } + else + { /* expand */ + if (cxy > 0) + { /* position */ + float pos; + + pos = (float)cxy / 100 * xpmwidthheight - (cincr / 2); + cp = xpmwidthheight - cincr; + if (pos <= 0) + cp = 0; + else if (pos < cp) + cp = pos; + } + cxy = 0; + cwh = widthheight; + } + } + cincr /= widthheight; + *wh = cwh; + *xy = cxy; + *incr = cincr; + *p = cp; } Pixmap rxvt_term::set_bgPixmap (const char *file) { - char *f; + char *f; - assert(file != NULL); + assert(file != NULL); - if (bgPixmap.pixmap != None) { - XFreePixmap(Xdisplay, bgPixmap.pixmap); - bgPixmap.pixmap = None; + if (bgPixmap.pixmap != None) + { + XFreePixmap(Xdisplay, bgPixmap.pixmap); + bgPixmap.pixmap = None; } - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[Color_bg]); - - if (*file != '\0') { -/* XWindowAttributes attr; */ + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[Color_bg]); - /* - * we already have the required attributes - */ -/* XGetWindowAttributes(Xdisplay, TermWin.vt, &attr); */ - - xpmAttr.closeness = 30000; - xpmAttr.colormap = XCMAP; - xpmAttr.visual = XVISUAL; - xpmAttr.depth = XDEPTH; - xpmAttr.valuemask = (XpmCloseness | XpmColormap | XpmVisual | - XpmDepth | XpmSize | XpmReturnPixels); - - /* search environment variables here too */ - f = (char *)rxvt_File_find(file, ".xpm", rs[Rs_path]); - if (f == NULL - || XpmReadFileToPixmap(Xdisplay, Xroot, f, - &bgPixmap.pixmap, NULL, - &xpmAttr)) { - char *p; - - /* semi-colon delimited */ - if ((p = STRCHR(file, ';')) == NULL) - p = STRCHR(file, '\0'); - - rxvt_print_error("couldn't load XPM file \"%.*s\"", (p - file), - file); - } - free(f); + if (*file != '\0') + { + /* XWindowAttributes attr; */ + + /* + * we already have the required attributes + */ + /* XGetWindowAttributes(Xdisplay, TermWin.vt, &attr); */ + + xpmAttr.closeness = 30000; + xpmAttr.colormap = XCMAP; + xpmAttr.visual = XVISUAL; + xpmAttr.depth = XDEPTH; + xpmAttr.valuemask = (XpmCloseness | XpmColormap | XpmVisual | + XpmDepth | XpmSize | XpmReturnPixels); + + /* search environment variables here too */ + f = (char *)rxvt_File_find(file, ".xpm", rs[Rs_path]); + if (f == NULL + || XpmReadFileToPixmap(Xdisplay, Xroot, f, + &bgPixmap.pixmap, NULL, + &xpmAttr)) + { + char *p; + + /* semi-colon delimited */ + if ((p = STRCHR(file, ';')) == NULL) + p = STRCHR(file, '\0'); + + rxvt_print_error("couldn't load XPM file \"%.*s\"", (p - file), + file); + } + free(f); } - resize_pixmap (); - return bgPixmap.pixmap; + resize_pixmap (); + return bgPixmap.pixmap; } #endif /* XPM_BACKGROUND */