Exemplo n.º 1
0
Arquivo: thai.c Projeto: razvanm/mrxvt
/* EXTPROTO */
int
ThaiPixel2Col (rxvt_t* r, int page, int x, int y)
{
	int row;             /* row storing data */
	int i;               /* byte offset index */
	int xpixel;          /* dummy x pixel */
	char *str;           /* drawn_text pointer */
	XFontStruct *wf;     /* font */

	/* locate buffer storing data */
	row = Pixel2Row(y);
	MAX_IT(row, 0);
	MIN_IT(row, r->TermWin.nrow - 1);
	str = PVTS(r, page)->drawn_text[row];

	/* access to font structure */
	wf = r->TermWin.font;

	/* increase byte offset until we get to target x */
	i = 0;
	xpixel = FONT_WIDTH(wf, str[0]);
	x -= r->TermWin.int_bwidth;
	while (xpixel <= x && i < r->TermWin.ncol){
		i++;
		xpixel += FONT_WIDTH(wf, str[i]); /* wf->per_char[char_num].width;  */
	}

	MAX_IT(i, 0);
	MIN_IT(i, r->TermWin.ncol);
	return i;
}
Exemplo n.º 2
0
Arquivo: pixmap.c Projeto: mcgrew/lxvt
/* EXTPROTO */
Pixmap
rxvt_load_bg_pixmap(rxvt_t *r, int page, const char *file)
{
    Pixmap	pixmap;
    long	w = 0, h = 0;

    assert(file != NULL);

    pixmap = rxvt_load_pixmap (r, file, &w, &h);
    if (IS_PIXMAP(PVTS(r, page)->bg.pixmap))
	XFreePixmap (r->Xdisplay, PVTS(r, page)->bg.pixmap);
    PVTS(r, page)->bg.pixmap = pixmap;

    if( NOT_PIXMAP(pixmap) )
    {
	if( page == ATAB(r) )
	{
	    /* Force resetting the background color */
	    r->fgbg_tabnum = -1;
	    rxvt_set_vt_colors( r, page );
	}

	return None;
    }

    PVTS(r, page)->xpm_attr.closeness = 30000;
    PVTS(r, page)->xpm_attr.colormap = XCMAP;
    PVTS(r, page)->xpm_attr.visual = XVISUAL;
    PVTS(r, page)->xpm_attr.depth = XDEPTH;
    PVTS(r, page)->xpm_attr.valuemask = (XpmCloseness | XpmColormap |
	    XpmVisual | XpmDepth | XpmSize | XpmReturnPixels);
    PVTS(r, page)->xpm_attr.width = w;
    PVTS(r, page)->xpm_attr.height = h;
    rxvt_resize_pixmap(r, page);
    return (pixmap);
}
Exemplo n.º 3
0
/* EXTPROTO */
void
rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname)
{
#ifdef UTEMPTER_SUPPORT
    utempter_add_record (PVTS(r)->cmd_fd, hostname);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *utx = &(PVTS(r)->utx);
#endif
#ifdef HAVE_UTMP_PID
    int             i;
#endif
    char            ut_id[5];
    struct passwd  *pwent = getpwuid(getuid());

    if (!STRNCMP(pty, "/dev/", 5))
	pty += 5;	/* skip /dev/ prefix */

    if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) {
	STRNCPY(ut_id, (pty + 3), sizeof(ut_id));
    }
#ifdef HAVE_UTMP_PID
    else if (sscanf(pty, "pts/%d", &i) == 1)
	sprintf(ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
#endif
    else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) {
	rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty);
	return;
    }

#ifdef HAVE_STRUCT_UTMP
    MEMSET(ut, 0, sizeof(struct utmp));
# ifdef HAVE_UTMP_PID
    setutent();
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_type = DEAD_PROCESS;
    getutid(ut);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
    utx->ut_type = DEAD_PROCESS;
    getutxid(utx);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
#endif

#ifdef HAVE_STRUCT_UTMP
    STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line));
    ut->ut_time = time(NULL);
# ifdef HAVE_UTMP_PID
    STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_user));
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_time = time(NULL);
    ut->ut_pid = PVTS(r)->cmd_pid;
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
    ut->ut_type = USER_PROCESS;
    pututline(ut);
    endutent();		/* close the file */
    PVTS(r)->utmp_pos = 0;
# else
    STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line));
    STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(utx->ut_user));
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
    utx->ut_pid = PVTS(r)->cmd_pid;
# ifdef HAVE_UTMPX_HOST
    STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host));
# endif
    utx->ut_type = USER_PROCESS;
    pututxline(utx);
    endutxent();	/* close the file */
    PVTS(r)->utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
    {
	int             i;
# ifdef HAVE_TTYSLOT
	i = ttyslot();
	if (rxvt_write_bsd_utmp(i, ut))
	    PVTS(r)->utmp_pos = i;
# else
	FILE           *fd0;

	if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) {
	    char            buf[256], name[256];

	    buf[sizeof(buf) - 1] = '\0';
	    for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) {
		if (*buf == '#' || sscanf(buf, "%s", name) != 1)
		    continue;
		if (!STRCMP(ut->ut_line, name)) {
		    if (!rxvt_write_bsd_utmp(i, ut))
			i = 0;
		    PVTS(r)->utmp_pos = i;
		    fclose(fd0);
		    break;
		}
		i++;
	    }
	    fclose(fd0);
	}
# endif
    }
#endif

#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

#endif	/* UTEMPTER_SUPPORT */

#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE)
    if (ISSET_OPTION(r, Opt_loginShell))
	rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname);
#endif

}
Exemplo n.º 4
0
/* EXTPROTO */
void
rxvt_cleanutent(rxvt_t *r)
{
#ifdef UTEMPTER_SUPPORT
    utempter_remove_record (PVTS(r)->cmd_fd);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *tmputx, *utx = &(PVTS(r)->utx);
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    MEMSET(ut, 0, sizeof(struct utmp));
    setutent();
    STRNCPY(ut->ut_id, PVTS(r)->ut_id, sizeof(ut->ut_id));
    ut->ut_type = USER_PROCESS;
    {
	struct utmp    *tmput = getutid(ut);

	if (tmput)	/* position to entry in utmp file */
	    ut = tmput;
    }
    ut->ut_type = DEAD_PROCESS;
# else 
    MEMSET(ut->ut_name, 0, sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    MEMSET(ut->ut_host, 0, sizeof(ut->ut_host));
#  endif
# endif
    ut->ut_time = time(NULL);
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, PVTS(r)->ut_id, sizeof(utx->ut_id));
    utx->ut_type = USER_PROCESS;
    if ((tmputx = getutxid(utx)))   /* position to entry in utmp file */
	utx = tmputx;
    utx->ut_type = DEAD_PROCESS;
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
#endif

    /*
     * Write ending wtmp entry
     */
#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

    /*
     * Write utmp entry
     */
#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    if (ut->ut_pid == PVTS(r)->cmd_pid)
	pututline(ut);
    endutent();
# else
    MEMSET(ut, 0, sizeof(struct utmp));
    rxvt_write_bsd_utmp(PVTS(r)->utmp_pos, ut);
# endif
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    if (utx->ut_pid == PVTS(r)->cmd_pid)
	pututxline(utx);
    endutxent();
#endif

#endif	/* UTEMPTER_SUPPORT */
}
Exemplo n.º 5
0
Arquivo: pixmap.c Projeto: mcgrew/lxvt
/* EXTPROTO */
int
rxvt_scale_pixmap(rxvt_t *r, int page, 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 = &(PVTS(r, page)->bg);

#define MAXLEN_GEOM	sizeof("[1000x1000+1000+1000]")

    if (geom == NULL)
	return 0;
    str = 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));
	rxvt_xterm_seq(r, page, XTerm_title, str, CHAR_ST);
	rxvt_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++;
    }
    }
    rxvt_free(str);
    return changed;
}
Exemplo n.º 6
0
Arquivo: pixmap.c Projeto: mcgrew/lxvt
/* EXTPROTO */
void
rxvt_resize_pixmap(rxvt_t *r, int page)
{
    XGCValues	    gcvalue;
    GC		    gc;
    unsigned int    width = VT_WIDTH(r);
    unsigned int    height = VT_HEIGHT(r);

    if (IS_PIXMAP(PVTS(r, page)->pixmap))
	XFreePixmap(r->Xdisplay, PVTS(r, page)->pixmap);

    if (NOT_PIXMAP(PVTS(r, page)->bg.pixmap))
	/* So be it: I'm not using pixmaps */
	return;

    gcvalue.foreground = r->pixColorsFocus[Color_bg];
    gc = XCreateGC(r->Xdisplay, PVTS(r, page)->vt, GCForeground, &gcvalue);

    if (IS_GC(gc) && IS_PIXMAP(PVTS(r, page)->bg.pixmap)) {
	/* we have a specified pixmap */
	unsigned int	w = PVTS(r, page)->bg.w;
	unsigned int	h = PVTS(r, page)->bg.h;
	unsigned int	x = PVTS(r, page)->bg.x;
	unsigned int	y = PVTS(r, page)->bg.y;
	unsigned int	xpmh = PVTS(r, page)->xpm_attr.height;
	unsigned int	xpmw = PVTS(r, page)->xpm_attr.width;
	unsigned int	pixmapw, pixmaph;

	/*
	 * 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 */
	    PVTS(r, page)->pixmap = XCreatePixmap(r->Xdisplay,
		PVTS(r, page)->vt, xpmw, xpmh, (unsigned int)XDEPTH);
	    XCopyArea(r->Xdisplay, PVTS(r, page)->bg.pixmap,
		PVTS(r, page)->pixmap, gc, 0, 0, xpmw, xpmh, 0, 0);

	    pixmapw = xpmw;
	    pixmaph = xpmh;
	}
	else {
	    float	  incr, p;
	    Pixmap	  tmp;

	    PVTS(r, page)->pixmap = XCreatePixmap(r->Xdisplay,
		PVTS(r, page)->vt, width, height, (unsigned int)XDEPTH);

	    /* horizontal scaling */
	    rxvt_pixmap_incr(&w, &x, &incr, &p, width, xpmw);

	    tmp = XCreatePixmap(r->Xdisplay, PVTS(r, page)->vt,
		    width, xpmh, (unsigned int)XDEPTH);
	    XFillRectangle(r->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(r->Xdisplay, PVTS(r, page)->bg.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(r->Xdisplay, PVTS(r, page)->pixmap, gc,
		    0, 0, width, y);
	    if (h < height)
		XFillRectangle(r->Xdisplay, PVTS(r, page)->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(r->Xdisplay, tmp, PVTS(r, page)->pixmap, gc,
		    0, (int)p, width, 1, 0, (int)y);
	    }
	    XFreePixmap(r->Xdisplay, tmp);

	    pixmapw = width;
	    pixmaph = height;
	}

#ifdef TINTING_SUPPORT
# ifdef HAVE_LIBXRENDER
	xrenderShadeParentPixmap( r, PVTS(r, page)->pixmap,
		0, 0, pixmapw, pixmaph, False);
# else
	rxvt_shade_pixmap( r, PVTS(r, page)->pixmap,
		0, 0, pixmapw, pixmaph);
# endif
#endif	/* TINTING_SUPPORT */

	/* Free gc */
	XFreeGC(r->Xdisplay, gc);
    }

    XSetWindowBackgroundPixmap(r->Xdisplay, PVTS(r, page)->vt,
	PVTS(r, page)->pixmap);
# ifdef TRANSPARENT
    r->h->am_transparent = 0;
    r->h->am_pixmap_trans = 0;
# endif

    XClearWindow(r->Xdisplay, PVTS(r, page)->vt);

    XSync(r->Xdisplay, False);
}
Exemplo n.º 7
0
/* EXTPROTO */
int
rxvt_scrollbar_show_next(rxvt_t *r, int update, int last_top, int last_bot, int scroller_len)
{
	int			height;
	Drawable	s;
	int			page = ATAB(r);


	height = r->scrollBar.end + NEXT_SB_TBTN_HEIGHT + NEXT_SB_PAD;

	if (PVTS(r, page)->nscrolled == 0 || !update) {
		XClearArea (r->Xdisplay, r->scrollBar.win,
			0, 0, SB_WIDTH_NEXT + 1, height, False);

		CHOOSE_GC_FG(r, r->scrollBar.next_fg);
		XDrawRectangle(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
			0, NEXT_SB_BD_WIDTH, SB_WIDTH_NEXT,
			height + NEXT_SB_BD_WIDTH);

# ifdef TRANSPARENT
		/* set background color when there's no transparent */
		if (!((r->Options & Opt_transparent) &&
			(r->Options & Opt_transparent_scrollbar)))
# endif
#ifdef BACKGROUND_IMAGE
		/* set background color when there's no bg image */
		if (None == r->scrollBar.pixmap)
#endif
		XFillRectangle(r->Xdisplay, r->scrollBar.win, TILEGC,
			NEXT_SB_LPAD, 0, NEXT_SB_BTN_WIDTH, height);
	}

	if (PVTS(r, page)->nscrolled) {
		if (last_top < r->scrollBar.top || !update)	{
			/*
			** Area above the scroller
			*/
# ifdef TRANSPARENT
			/* clear background when there's transparent */
			if ((r->Options & Opt_transparent) &&
				(r->Options & Opt_transparent_scrollbar))
				XClearArea (r->Xdisplay, r->scrollBar.win,
					NEXT_SB_LPAD, NEXT_SB_PAD + last_top,
					NEXT_SB_BTN_WIDTH, r->scrollBar.top - last_top,
					False);
			else
# endif
# ifdef BACKGROUND_IMAGE
			/* clear background when there's bg image */
			if (None != r->scrollBar.pixmap)
				XClearArea (r->Xdisplay, r->scrollBar.win,
					NEXT_SB_LPAD, NEXT_SB_PAD + last_top,
					NEXT_SB_BTN_WIDTH, r->scrollBar.top - last_top,
					False);
			else
# endif
			XFillRectangle(r->Xdisplay, r->scrollBar.win, TILEGC,
				NEXT_SB_LPAD, NEXT_SB_PAD + last_top,
				NEXT_SB_BTN_WIDTH, r->scrollBar.top - last_top);
		}

		if (r->scrollBar.bot < last_bot || !update)	{
			/*
			** Area above the buttons but below the scroller
			*/
# ifdef TRANSPARENT
			/* clear background when there's transparent */
			if ((r->Options & Opt_transparent) &&
				(r->Options & Opt_transparent_scrollbar))
				XClearArea(r->Xdisplay, r->scrollBar.win,
					NEXT_SB_LPAD, r->scrollBar.bot + NEXT_SB_PAD,
					NEXT_SB_BTN_WIDTH, (last_bot - r->scrollBar.bot),
					False);
			else
# endif
# ifdef BACKGROUND_IMAGE
			/* clear background when there's bg image */
			if (None != r->scrollBar.pixmap)
				XClearArea (r->Xdisplay, r->scrollBar.win,
					NEXT_SB_LPAD, r->scrollBar.bot + NEXT_SB_PAD,
					NEXT_SB_BTN_WIDTH, (last_bot - r->scrollBar.bot),
					False);
			else
# endif
			XFillRectangle(r->Xdisplay, r->scrollBar.win, TILEGC,
				NEXT_SB_LPAD, r->scrollBar.bot + NEXT_SB_PAD,
				NEXT_SB_BTN_WIDTH, (last_bot - r->scrollBar.bot));
		}


		/*
		** Area of the scroller
		*/
# ifdef TRANSPARENT
		/* clear background when there's transparent */
		if ((r->Options & Opt_transparent) &&
			(r->Options & Opt_transparent_scrollbar))
			XClearArea (r->Xdisplay, r->scrollBar.win,
				NEXT_SB_LPAD, r->scrollBar.top + NEXT_SB_PAD,
				NEXT_SB_BTN_WIDTH, scroller_len/*-NEXT_SB_BTN_HEIGHT*/,
				False);
		else
# endif
# ifdef BACKGROUND_IMAGE
		/* clear background when there's bg image */
		if (None != r->scrollBar.pixmap)
			XClearArea (r->Xdisplay, r->scrollBar.win,
				NEXT_SB_LPAD, r->scrollBar.top + NEXT_SB_PAD,
				NEXT_SB_BTN_WIDTH, scroller_len/*-NEXT_SB_BTN_HEIGHT*/,
				False);
		else
# endif
		{
			CHOOSE_GC_FG(r, r->scrollBar.next_bg);
			XFillRectangle(r->Xdisplay, r->scrollBar.win,
				r->scrollBar.gc,
				NEXT_SB_LPAD, r->scrollBar.top + NEXT_SB_PAD,
				NEXT_SB_BTN_WIDTH, scroller_len/*-NEXT_SB_BTN_HEIGHT*/);
		}


		/*
		** Here comes the dimple in the scroller
		*/
		CHOOSE_GC_FG(r, r->scrollBar.next_white);
		XCopyArea(r->Xdisplay, DIMPLE, r->scrollBar.win,
				r->scrollBar.gc, 0, 0,
				DIMPLE_WIDTH, DIMPLE_HEIGHT,
				(SB_WIDTH_NEXT - DIMPLE_WIDTH) / 2,
				r->scrollBar.top + NEXT_BEVEL_ULEFT_WIDTH +
				(scroller_len - DIMPLE_HEIGHT) / 2);

		/*
		** Bevel around the scroller
		*/
		next_draw_bevel(r, r->scrollBar.win, NEXT_BEVEL_X,
			r->scrollBar.top + NEXT_SB_PAD, NEXT_SB_BTN_WIDTH,
			scroller_len);
		/*
		** Bevel around the buttons
		*/
		next_draw_bevel(r, r->scrollBar.win, NEXT_BEVEL_X,
			height - NEXT_SB_DBTN_HEIGHT, NEXT_SB_BTN_WIDTH,
			NEXT_SB_BTN_HEIGHT);
		next_draw_bevel(r, r->scrollBar.win, NEXT_BEVEL_X,
			height - NEXT_SB_SBTN_HEIGHT, NEXT_SB_BTN_WIDTH,
			NEXT_SB_BTN_HEIGHT);

		/*
		** Top button
		*/
		CHOOSE_GC_FG(r, r->scrollBar.next_white);
		s = (scrollbar_isUp()) ? HIUPARROW : UPARROW;
		XCopyArea(r->Xdisplay, s, r->scrollBar.win, r->scrollBar.gc,
			0, 0,
			ARROW_WIDTH, ARROW_HEIGHT, NEXT_BTN_FACE_X,
			height-NEXT_SB_DBTN_HEIGHT+NEXT_BEVEL_ULEFT_WIDTH);

		/*
		** Bottom button
		*/
		s = (scrollbar_isDn()) ? HIDNARROW : DNARROW;
		XCopyArea(r->Xdisplay, s, r->scrollBar.win, r->scrollBar.gc,
			0, 0,
			ARROW_WIDTH, ARROW_HEIGHT, NEXT_BTN_FACE_X,
			height-NEXT_SB_SBTN_HEIGHT+NEXT_BEVEL_ULEFT_WIDTH);
	}

	return 1;
}