Exemplo n.º 1
0
void drawinput(Input *i)
{
	char buf[512], *s;
	int x, y, curpos, textw, innerw;
	size_t n;
	unsigned long *col = hasfocus(i->win) ? dc.sel : dc.norm;

	XSetForeground(dpy, dc.gc, col[ColBG]);
	XFillRectangle(dpy, dc.drawable, dc.gc, 0, 0, i->w, 2 * i->h);

	/* draw label */
	n = strlen(i->label);
	x = i->xpadding;
	y = (i->h - dc.font.height) / 2 + dc.font.ascent;
	XSetForeground(dpy, dc.gc, col[ColFG]);
	drawtext(x, y, i->label, n);
	x += textnw(i->label, n);

	/* draw input */
	if (i->hidden) {
		n = numrunes(i->text, sizeof(i->text));
		memset(buf, '*', n);
		buf[n] = 0;
		curpos = textnw(buf, numrunes(i->text, i->cursor));
		s = buf;
	} else {
		n = strlen(i->text);
		curpos = textnw(i->text, i->cursor);
		s = i->text;
	}

	y += i->h;
	textw = textnw(s, strlen(s));
	innerw = i->w - i->xpadding - x;
	if (curpos < i->xshift)
		i->xshift = curpos;
	else if (curpos > i->xshift + innerw)
		i->xshift = curpos - innerw;
	if (i->xshift && textw < i->xshift + innerw)
		i->xshift = MAX(0, textw - innerw);

	drawtext(1 - i->xshift, y, s, n);
	if (col == dc.sel)
		XFillRectangle(dpy, dc.drawable, dc.gc, curpos - i->xshift,
				y - dc.font.ascent, 1, dc.font.height);

	XCopyArea(dpy, dc.drawable, i->win, dc.gc, 0, 0, x, i->h, 0, 0);
	XCopyArea(dpy, dc.drawable, i->win, dc.gc, 0, i->h, i->w - x, i->h, x, 0);
	XSync(dpy, False);
}
Exemplo n.º 2
0
void
drawmenu(void) {
	int curpos;
	Item *item;

	dc->x = 0;
	dc->y = 0;
	dc->h = bh;
	drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));

	if(prompt && *prompt) {
		dc->w = promptw;
		drawtext(dc, prompt, selcol);
		dc->x = dc->w;
	}
	/* draw input field */
	dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
	drawtext(dc, text, normcol);
	if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
		drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));

    /* // Draw hits */
    dc->w = textw(dc, hitstxt);
    dc->x = mw - dc->w;
    drawtext(dc, hitstxt, selcol);
    dc->x = 0;

	if(lines > 0) {
		/* draw vertical list */
		dc->w = mw - dc->x;
		for(item = curr; item != next; item = item->right) {
			dc->y += dc->h;
			drawtext(dc, item->text, (item == sel) ? selcol :
			                         (item->out)   ? outcol : normcol);
		}
	}
	else if(matches) {
		/* draw horizontal list */
		dc->x += inputw;
		dc->w = textw(dc, "<");
		if(curr->left)
			drawtext(dc, "<", normcol);
		for(item = curr; item != next; item = item->right) {
			dc->x += dc->w;
			dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">"));
			drawtext(dc, item->text, (item == sel) ? selcol :
			                         (item->out)   ? outcol : normcol);
		}
		dc->w = textw(dc, ">");
		dc->x = mw - dc->w;
		if(next)
			drawtext(dc, ">", normcol);
	}
	mapdc(dc, win, mw, mh);
}
Exemplo n.º 3
0
void
drawmenu(void) {
	int curpos;
	Item *item;

	dc->x = 0;
	dc->y = 0;
	dc->h = bh;
	drawrect(dc, 0, 0, mw, mh, True, normcol->BG);

	if(prompt && *prompt) {
		dc->w = promptw;
		drawtext(dc, prompt, selcol);
		dc->x = dc->w;
	}
	/* draw input field */
	dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
	drawtext(dc, text, normcol);
	if((curpos = textnw(dc, text, cursor) + dc->font.height/2) < dc->w)
		drawrect(dc, curpos, (dc->h - dc->font.height)/2 + 1, 1, dc->font.height -1, True, normcol->FG);

    if(!quiet || strlen(text) > 0) {    
        if(lines > 0) {
            /* draw vertical list */
            dc->w = mw - dc->x;
            for(item = curr; item != next; item = item->right) {
                dc->y += dc->h;
                drawtext(dc, item->text, (item == sel) ? selcol : normcol);
            }
        }
        else if(matches) {
            /* draw horizontal list */
            dc->x += inputw;
            dc->w = textw(dc, "<");
            if(curr->left)
                drawtext(dc, "<", normcol);
            for(item = curr; item != next; item = item->right) {
                dc->x += dc->w;
                dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">"));
                drawtext(dc, item->text, (item == sel) ? selcol : normcol);
            }
            dc->w = textw(dc, ">");
            dc->x = mw - dc->w;
            if(next)
                drawtext(dc, ">", normcol);
        }
    }
	mapdc(dc, win, mw, mh);
}
Exemplo n.º 4
0
void
drawtext(DC *dc, int scrnum, const char *text, ColorSet *col) {
	char buf[BUFSIZ];
	size_t mn, n = strlen(text);
  DM *m = &dc->menus[scrnum];
	/* shorten text if necessary */
	for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) + dc->font.height/2 > m->cw; mn--)
		if(mn == 0)
			return;
	memcpy(buf, text, mn);
	if(mn < n)
		for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
	drawrect(dc, scrnum, 0, 0, m->cw, m->ch, True, col->BG);
	drawtextn(dc, scrnum, buf, mn, col);
}
Exemplo n.º 5
0
Arquivo: draw.c Projeto: Yomin/dmenu
void
drawtext(DC *dc, const char *text, Bool fill, unsigned long col[ColLast]) {
	char buf[BUFSIZ];
	size_t mn, n = strlen(text);

	/* shorten text if necessary */
	for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) + dc->font.height/2 > dc->w; mn--)
		if(mn == 0)
			return;
	memcpy(buf, text, mn);
	if(mn < n)
		for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');

	if(fill)
	    drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
	drawtextn(dc, buf, mn, col);
}
Exemplo n.º 6
0
void drawtext(DC * dc, const char *text, ColorSet * col)
{
        char buf[BUFSIZ];
        size_t mn, n = strlen(text);

        /* shorten text if necessary */
        for (mn = MIN(n, sizeof buf);
             textnw(dc, text, mn) + dc->font.height / 2 > dc->w; mn--)
                if (mn == 0)
                        return;
        memcpy(buf, text, mn);
        if (mn < n)
                for (n = MAX(mn - 3, 0); n < mn; buf[n++] = '.') ;

        drawrect(dc, 0, 0, dc->w, dc->h, true, col->BG);
        drawtextn(dc, buf, mn, col);
}
Exemplo n.º 7
0
// draw text
void drawtext(DC *dc, const char * text, ColorSet *col) {
    char buf[MAX_TITLE_LENGTH];

    /* shorten text if necessary */
    size_t n = strlen(text);
    size_t mn = MIN(n, sizeof buf);
    for(; textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--) {
        if(mn == 0) {
            return; // dont draw text (there isn't any)
        }
    }

    memcpy(buf, text, mn);

    /* if the text was shortened, add some elipses */
    if(mn < n)
        for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');

    drawrect_modifier(dc, 0, dc->color_border_pixels,
                          dc->w, dc->h-(2*dc->color_border_pixels),
                          True, col->BG);
    drawtextn(dc, buf, mn, col);
}
Exemplo n.º 8
0
void
drawentry(Entry *e)
{
    int x, y, h, len;
    XRectangle r = { e->x, e->y, e->w, e->h };
    const char *l;
    ulong *col;

    if(e->pressed)
        col = dc.press;
    else if(e->highlighted)
        col = dc.high;
    else
        col = dc.norm;

    XSetForeground(dpy, dc.gc, col[ColBG]);
    XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
    XSetForeground(dpy, dc.gc, dc.norm[ColFG]);
    r.height -= 1;
    r.width -= 1;
    XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
    XSetForeground(dpy, dc.gc, col[ColFG]);

    l = e->label;
    len = strlen(l);
    h = dc.font.height;
    y = e->y + (e->h / 2) - (h / 2) + dc.font.ascent;
    x = e->x + (e->w / 2) - (textnw(l, len) / 2);
    if(dc.font.set) {
        XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, l,
                      len);
    } else
        XDrawString(dpy, dc.drawable, dc.gc, x, y, l, len);
    XCopyArea(dpy, dc.drawable, win, dc.gc, e->x, e->y, e->w, e->h,
              e->x, e->y);
}
Exemplo n.º 9
0
int
textw(DC *dc, const char *text) {
	return textnw(dc, text, strlen(text)) + dc->font.height;
}
Exemplo n.º 10
0
Arquivo: draw.c Projeto: dylex/dzen
char *
parse_line(const char *line, int lnr, int align, int reverse, int nodraw) {
	/* bitmaps */
	unsigned int bm_w, bm_h;
	int bm_xh, bm_yh;
	/* rectangles, cirlcles*/
	int rectw, recth, rectx, recty;
	/* positioning */
	int n_posx, n_posy, set_posy=0;
	int px=0, py=0, opx=0;
	int i, next_pos=0, j=0, h=0, tw=0;
	/* buffer pos */
	const char *linep=NULL;
	/* fonts */
	int font_was_set=0;
	/* position */
	int pos_is_fixed = 0;
	/* block alignment */
	int block_align = -1;
	int block_width = -1;
	/* clickable area y tracking */
	int max_y=-1;

	/* temp buffers */
	char lbuf[MAX_LINE_LEN], *rbuf = NULL;

	/* parser state */
	int t=-1, nobg=0;
	char *tval=NULL;

	/* X stuff */
	long lastfg = dzen.norm[ColFG], lastbg = dzen.norm[ColBG];
	Fnt *cur_fnt = NULL;
#ifndef DZEN_XFT
	XGCValues gcv;
#endif
	Drawable pm=0, bm;
#ifdef DZEN_XPM
	int free_xpm_attrib = 0;
	Pixmap xpm_pm;
	XpmAttributes xpma;
	XpmColorSymbol xpms;
#endif

#ifdef DZEN_XFT
	XftDraw *xftd=NULL;
	XftColor xftc;
	char *xftcs;
	int xftcs_f=0;
	char *xftcs_bg;
	int xftcs_bgf=0;

	xftcs    = (char *)dzen.fg;
    xftcs_bg = (char *)dzen.bg;
#endif

	/* icon cache */
	int ip;

	/* parse line and return the text without control commands */
	if(nodraw) {
		rbuf = emalloc(MAX_LINE_LEN);
		rbuf[0] = '\0';
		if( (lnr + dzen.slave_win.first_line_vis) >= dzen.slave_win.tcnt)
			line = NULL;
		else
			line = dzen.slave_win.tbuf[dzen.slave_win.first_line_vis+lnr];

	}
	/* parse line and render text */
	else {
		h = dzen.font.height;
		py = (dzen.line_height - h) / 2;
		xorig[LNR2WINDOW(lnr)] = 0;
		
		if(lnr != -1) {
			pm = XCreatePixmap(dzen.dpy, RootWindow(dzen.dpy, DefaultScreen(dzen.dpy)), dzen.slave_win.width,
					dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen));
		}
		else {
			pm = XCreatePixmap(dzen.dpy, RootWindow(dzen.dpy, DefaultScreen(dzen.dpy)), dzen.title_win.width,
					dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen));
		}

#ifdef DZEN_XFT
		xftd = XftDrawCreate(dzen.dpy, pm, DefaultVisual(dzen.dpy, dzen.screen), 
				DefaultColormap(dzen.dpy, dzen.screen));
#endif

		if(!reverse) {
			XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColBG]);
#ifdef DZEN_XPM
			xpms.pixel = dzen.norm[ColBG];
#endif
#ifdef DZEN_XFT
			xftcs_bg = (char *)dzen.bg;
			xftcs_bgf = 0;
#endif
		}
		else {
			XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColFG]);
#ifdef DZEN_XPM
			xpms.pixel = dzen.norm[ColFG];
#endif
		}
		XFillRectangle(dzen.dpy, pm, dzen.tgc, 0, 0, dzen.w, dzen.h);

		if(!reverse) {
			XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColFG]);
		}
		else {
			XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColBG]);
		}

#ifdef DZEN_XPM
		xpms.name = NULL;
		xpms.value = (char *)"none";

		xpma.colormap = DefaultColormap(dzen.dpy, dzen.screen);
		xpma.depth = DefaultDepth(dzen.dpy, dzen.screen);
		xpma.visual = DefaultVisual(dzen.dpy, dzen.screen);
		xpma.colorsymbols = &xpms;
		xpma.numsymbols = 1;
		xpma.valuemask = XpmColormap|XpmDepth|XpmVisual|XpmColorSymbols;
#endif

#ifndef DZEN_XFT 
		if(!dzen.font.set){
			gcv.font = dzen.font.xfont->fid;
			XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv);
		}
#endif
		cur_fnt = &dzen.font;

		if( lnr != -1 && (lnr + dzen.slave_win.first_line_vis >= dzen.slave_win.tcnt)) {
			XCopyArea(dzen.dpy, pm, dzen.slave_win.drawable[lnr], dzen.gc,
					0, 0, px, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0);
			XFreePixmap(dzen.dpy, pm);
			return NULL;
		}
	}

	linep = line;
	while(1) {
		if(*linep == ESC_CHAR || *linep == '\0') {
			lbuf[j] = '\0';

			/* clear _lock_x at EOL so final width is correct */
			if(*linep=='\0')
				pos_is_fixed=0;

			if(nodraw) {
				strcat(rbuf, lbuf);
			}
			else {
				if(t != -1 && tval) {
					switch(t) {
						case icon:
							if(MAX_ICON_CACHE && (ip=search_icon_cache(tval)) != -1) {
								int y;
								XCopyArea(dzen.dpy, icons[ip].p, pm, dzen.tgc,
										0, 0, icons[ip].w, icons[ip].h, px, y=(set_posy ? py :
										(dzen.line_height >= (signed)icons[ip].h ?
										(dzen.line_height - icons[ip].h)/2 : 0)));
								px += !pos_is_fixed ? icons[ip].w : 0;
								max_y = MAX(max_y, y+icons[ip].h);
							} else {
								int y;
								if(XReadBitmapFile(dzen.dpy, pm, tval, &bm_w,
											&bm_h, &bm, &bm_xh, &bm_yh) == BitmapSuccess
										&& (h/2 + px + (signed)bm_w < dzen.w)) {
									setcolor(&pm, px, bm_w, lastfg, lastbg, reverse, nobg);

									XCopyPlane(dzen.dpy, bm, pm, dzen.tgc,
											0, 0, bm_w, bm_h, px, y=(set_posy ? py :
											(dzen.line_height >= (int)bm_h ?
												(dzen.line_height - (int)bm_h)/2 : 0)), 1);
									XFreePixmap(dzen.dpy, bm);
									px += !pos_is_fixed ? bm_w : 0;
									max_y = MAX(max_y, y+bm_h);
								}
#ifdef DZEN_XPM
								else if(XpmReadFileToPixmap(dzen.dpy, dzen.title_win.win, tval, &xpm_pm, NULL, &xpma) == XpmSuccess) {
									setcolor(&pm, px, xpma.width, lastfg, lastbg, reverse, nobg);

									if(MAX_ICON_CACHE)
										cache_icon(tval, xpm_pm, xpma.width, xpma.height);

									XCopyArea(dzen.dpy, xpm_pm, pm, dzen.tgc,
											0, 0, xpma.width, xpma.height, px, y=(set_posy ? py :
											(dzen.line_height >= (int)xpma.height ?
												(dzen.line_height - (int)xpma.height)/2 : 0)));
									px += !pos_is_fixed ? xpma.width : 0;
									max_y = MAX(max_y, y+xpma.height);

									/* freed by cache_icon() */
									//XFreePixmap(dzen.dpy, xpm_pm);
									free_xpm_attrib = 1;
								}
#endif
							}
							break;


						case rect:
							get_rect_vals(tval, &rectw, &recth, &rectx, &recty);
							recth = recth > dzen.line_height ? dzen.line_height : recth;
							if(set_posy)
								py += recty;
							recty =	recty == 0 ? (dzen.line_height - recth)/2 :
								(dzen.line_height - recth)/2 + recty;
							px += !pos_is_fixed ? rectx : 0;
							setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg);

							XFillRectangle(dzen.dpy, pm, dzen.tgc, px,
									set_posy ? py :
									((int)recty < 0 ? dzen.line_height + recty : recty),
									rectw, recth);

							px += !pos_is_fixed ? rectw : 0;
							break;

						case recto:
							get_rect_vals(tval, &rectw, &recth, &rectx, &recty);
							if (!rectw) break;

							recth = recth > dzen.line_height ? dzen.line_height-2 : recth-1;
							if(set_posy)
								py += recty;
							recty =	recty == 0 ? (dzen.line_height - recth)/2 :
								(dzen.line_height - recth)/2 + recty;
							px = (rectx == 0) ? px : rectx+px;
							/* prevent from stairs effect when rounding recty */
							if (!((dzen.line_height - recth) % 2)) recty--;
							setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg);
							XDrawRectangle(dzen.dpy, pm, dzen.tgc, px,
									set_posy ? py :
									((int)recty<0 ? dzen.line_height + recty : recty), rectw-1, recth);
							px += !pos_is_fixed ? rectw : 0;
							break;

						case circle:
							rectx = get_circle_vals(tval, &rectw, &recth);
							setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg);
							XFillArc(dzen.dpy, pm, dzen.tgc, px, set_posy ? py :(dzen.line_height - rectw)/2,
									rectw, rectw, 90*64, rectx>1?recth*64:64*360);
							px += !pos_is_fixed ? rectw : 0;
							break;

						case circleo:
							rectx = get_circle_vals(tval, &rectw, &recth);
							setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg);
							XDrawArc(dzen.dpy, pm, dzen.tgc, px, set_posy ? py : (dzen.line_height - rectw)/2,
									rectw, rectw, 90*64, rectx>1?recth*64:64*360);
							px += !pos_is_fixed ? rectw : 0;
							break;

						case pos:
							if(tval[0]) {
								int r=0;
								r = get_pos_vals(tval, &n_posx, &n_posy);
								if( (r == 1 && !set_posy))
									set_posy=0;
								else if (r == 5) {
									switch(n_posx) {
										case LOCK_X:
											pos_is_fixed = 1;
											break;
										case UNLOCK_X:
											pos_is_fixed = 0;
											break;
										case LEFT:
											px = 0;
											break;
										case RIGHT:
											px = dzen.w;
											break;
										case CENTER:
											px = dzen.w/2;
											break;
										case BOTTOM:
											set_posy = 1;
											py = dzen.line_height;
											break;
										case TOP:
											set_posy = 1;
											py = 0;
											break;
									}
								} else
									set_posy=1;

								if(r != 2)
									px = px+n_posx<0? 0 : px + n_posx;
								if(r != 1) 
									py += n_posy;
							} else {
								set_posy = 0;
								py = (dzen.line_height - dzen.font.height) / 2;
							}
							break;

						case abspos:
							if(tval[0]) {
								int r=0;
								if( (r=get_pos_vals(tval, &n_posx, &n_posy)) == 1 && !set_posy)
									set_posy=0;
								else
									set_posy=1;

								n_posx = n_posx < 0 ? n_posx*-1 : n_posx;
								if(r != 2)
									px = n_posx;
								if(r != 1)
									py = n_posy;
							} else {
								set_posy = 0;
								py = (dzen.line_height - dzen.font.height) / 2;
							}
							break;

						case ibg:
							nobg = atoi(tval);
							break;

						case bg:
							lastbg = tval[0] ? (unsigned)getcolor(tval) : dzen.norm[ColBG];
#ifdef DZEN_XFT
							if(xftcs_bgf) free(xftcs_bg);				
							if(tval[0]) {
								xftcs_bg = estrdup(tval);
								xftcs_bgf = 1;
							} else {
								xftcs_bg = (char *)dzen.bg;
								xftcs_bgf = 0;
							}
#endif							

							break;

						case fg:
							lastfg = tval[0] ? (unsigned)getcolor(tval) : dzen.norm[ColFG];
							XSetForeground(dzen.dpy, dzen.tgc, lastfg);
#ifdef DZEN_XFT
							if(tval[0]) {
								xftcs = estrdup(tval);
								xftcs_f = 1;
							} else {
								xftcs = (char *)dzen.fg;
								xftcs_f = 0;
							}
#endif							
							break;

						case fn:
							if(tval[0]) {
#ifndef DZEN_XFT		
								if(!strncmp(tval, "dfnt", 4)) {
									cur_fnt = &(dzen.fnpl[atoi(tval+4)]);

									if(!cur_fnt->set) {
										gcv.font = cur_fnt->xfont->fid;
										XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv);
									}
								}
								else
#endif					
									setfont(tval);
							}
							else {
								cur_fnt = &dzen.font;
#ifndef DZEN_XFT		
								if(!cur_fnt->set){
									gcv.font = cur_fnt->xfont->fid;
									XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv);
								}
#else
							setfont(dzen.fnt ? dzen.fnt : FONT);
#endif								
							}
							py = set_posy ? py : (dzen.line_height - cur_fnt->height) / 2;
							font_was_set = 1;
							break;
						case ca:
						{
							sens_w *w = &window_sens[LNR2WINDOW(lnr)];
							
							if(tval[0]) {
								click_a *area = &((*w).sens_areas[(*w).sens_areas_cnt]);
								if((*w).sens_areas_cnt < MAX_CLICKABLE_AREAS) {
									get_sens_area(tval, 
											&(*area).button, 
											LNR2WINDOW(lnr)*MAX_CLICKABLE_AREAS+(*w).sens_areas_cnt);
									(*area).start_x = px;
									(*area).start_y = py;
									(*area).end_y = py;
									max_y = py;
									(*area).active = 0;
									if(lnr == -1) {
										(*area).win = dzen.title_win.win;
									} else {
										(*area).win = dzen.slave_win.line[lnr];
									}
									(*w).sens_areas_cnt++;
								}
							} else {
									//find most recent unclosed area
									for(i = (*w).sens_areas_cnt - 1; i >= 0; i--)
										if(!(*w).sens_areas[i].active)
											break;
									if(i >= 0 && i < MAX_CLICKABLE_AREAS) {
										(*w).sens_areas[i].end_x = px;
										(*w).sens_areas[i].end_y = max_y;
										(*w).sens_areas[i].active = 1;
								}
							}
						}	break;
						case ba:
							if(tval[0])
								get_block_align_vals(tval, &block_align, &block_width);
							else
								block_align=block_width=-1;
							break;
					}
					free(tval);
				}

				/* check if text is longer than window's width */
				tw = textnw(cur_fnt, lbuf, strlen(lbuf));
				while((((tw + px) > (dzen.w)) || (block_align!=-1 && tw>block_width)) && j>=0) {
					lbuf[--j] = '\0';
					tw = textnw(cur_fnt, lbuf, strlen(lbuf));
				}
				
				opx = px;

				/* draw background for block */
				if(block_align!=-1 && !nobg) {
					setcolor(&pm, px, rectw, lastbg, lastbg, 0, nobg);
					XFillRectangle(dzen.dpy, pm, dzen.tgc, px, 0, block_width, dzen.line_height);
				}

				if(block_align==ALIGNRIGHT)
					px += (block_width - tw);
				else if(block_align==ALIGNCENTER)
					px += (block_width/2) - (tw/2);

				if(!nobg)
					setcolor(&pm, px, tw, lastfg, lastbg, reverse, nobg);
				
#ifndef DZEN_XFT
				if(cur_fnt->set)
					XmbDrawString(dzen.dpy, pm, cur_fnt->set,
							dzen.tgc, px, py + cur_fnt->ascent, lbuf, strlen(lbuf));
				else
					XDrawString(dzen.dpy, pm, dzen.tgc, px, py+dzen.font.ascent, lbuf, strlen(lbuf));
#else
				if(reverse) {
				XftColorAllocName(dzen.dpy, DefaultVisual(dzen.dpy, dzen.screen),
						DefaultColormap(dzen.dpy, dzen.screen),  xftcs_bg,  &xftc);
				} else {
				XftColorAllocName(dzen.dpy, DefaultVisual(dzen.dpy, dzen.screen),
						DefaultColormap(dzen.dpy, dzen.screen),  xftcs,  &xftc);
				}

				XftDrawStringUtf8(xftd, &xftc, 
						cur_fnt->xftfont, px, py + dzen.font.xftfont->ascent, (const FcChar8 *)lbuf, strlen(lbuf));

				if(xftcs_f) {
					free(xftcs);
					xftcs_f = 0;
				}
				if(xftcs_bgf) {
					free(xftcs_bg);
					xftcs_bgf = 0;
				}

#endif

				max_y = MAX(max_y, py+dzen.font.height);

				if(block_align==-1) {
					if(!pos_is_fixed || *linep =='\0')
						px += tw;
				} else {
					if(pos_is_fixed)
						px = opx;
					else
						px = opx+block_width;
				}

				block_align=block_width=-1;
			}

			if(*linep=='\0')
				break;

			j=0; t=-1; tval=NULL;
			next_pos = get_token(linep, &t, &tval);
			linep += next_pos;

			/* ^^ escapes */
			if(next_pos == 0)
				lbuf[j++] = *linep++;
		}
		else
			lbuf[j++] = *linep;

		linep++;
	}

	if(!nodraw) {
		/* expand/shrink dynamically */
		if(dzen.title_win.expand && lnr == -1){
			i = px;
			switch(dzen.title_win.expand) {
				case left:
					/* grow left end */
					otx = dzen.title_win.x_right_corner - i > dzen.title_win.x ?
						dzen.title_win.x_right_corner - i : dzen.title_win.x;
					XMoveResizeWindow(dzen.dpy, dzen.title_win.win, otx, dzen.title_win.y, px, dzen.line_height);
					break;
				case right:
					XResizeWindow(dzen.dpy, dzen.title_win.win, px, dzen.line_height);
					break;
			}

		} else {
			if(align == ALIGNLEFT)
				xorig[LNR2WINDOW(lnr)] = 0;
			if(align == ALIGNCENTER) {
				xorig[LNR2WINDOW(lnr)] = (lnr != -1) ?
					(dzen.slave_win.width - px)/2 :
					(dzen.title_win.width - px)/2;
			}
			else if(align == ALIGNRIGHT) {
				xorig[LNR2WINDOW(lnr)] = (lnr != -1) ?
					(dzen.slave_win.width - px) :
					(dzen.title_win.width - px);
			}
		}


		if(lnr != -1) {
			XCopyArea(dzen.dpy, pm, dzen.slave_win.drawable[lnr], dzen.gc,
                    0, 0, dzen.w, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0);
		}
		else {
			XCopyArea(dzen.dpy, pm, dzen.title_win.drawable, dzen.gc,
					0, 0, dzen.w, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0);
		}
		XFreePixmap(dzen.dpy, pm);

		/* reset font to default */
		if(font_was_set)
			setfont(dzen.fnt ? dzen.fnt : FONT);

#ifdef DZEN_XPM
		if(free_xpm_attrib) {
			XFreeColors(dzen.dpy, xpma.colormap, xpma.pixels, xpma.npixels, xpma.depth);
			XpmFreeAttributes(&xpma);
		}
#endif

#ifdef DZEN_XFT
		XftDrawDestroy(xftd);
#endif
	}

	return nodraw ? rbuf : NULL;
}
Exemplo n.º 11
0
void
setup(void)
{
    XSetWindowAttributes wa;
    XTextProperty str;
    XSizeHints *sizeh;
    XClassHint *ch;
    int i, sh, sw, ls;

    /* init screen */
    screen = DefaultScreen(dpy);
    root = RootWindow(dpy, screen);
    sw = DisplayWidth(dpy, screen) - 1;
    sh = DisplayHeight(dpy, screen) - 1;
    initfont(font);

    /* init atoms */

    /* init appearance */

    for (i = 0, www = 0; i < nentries; i++) {
        ls = textnw(entries[i]->label,
                    strlen(entries[i]->label));
        if (ls > www)
            www = ls;
    }
    www *= widthscaling;

    if (!ww) {
        if (horizontal) {
            ww = www * nentries;
        } else {
            ww = www;
        }
    }
    if (!wh) {
        if (horizontal) {
            wh = dc.font.height * heightscaling;
        } else {
            wh = nentries * dc.font.height * heightscaling;
        }
    }
    if (!wy)
        wy = (sh - wh) / 2;
    if (wy < 0)
        wy = sh + wy - wh;
    if (!wx)
        wx = (sw - ww) / 2;
    if (wx < 0)
        wx = sw + wx - ww;

    dc.norm[ColBG] = getcolor(normbgcolor);
    dc.norm[ColFG] = getcolor(normfgcolor);
    dc.press[ColBG] = getcolor(pressbgcolor);
    dc.press[ColFG] = getcolor(pressfgcolor);
    dc.high[ColBG] = getcolor(highlightbgcolor);
    dc.high[ColFG] = getcolor(highlightfgcolor);

    dc.drawable = XCreatePixmap(dpy, root, ww, wh, DefaultDepth(dpy, screen));
    dc.gc = XCreateGC(dpy, root, 0, 0);
    if(!dc.font.set)
        XSetFont(dpy, dc.gc, dc.font.xfont->fid);
    for(i = 0; i < nentries; i++)
        entries[i]->pressed = 0;

    wa.override_redirect = !wmborder;
    wa.border_pixel = dc.norm[ColFG];
    wa.background_pixel = dc.norm[ColBG];
    win = XCreateWindow(dpy, root, wx, wy, ww, wh, 0,
                        CopyFromParent, CopyFromParent, CopyFromParent,
                        CWOverrideRedirect | CWBorderPixel | CWBackingPixel, &wa);
    XSelectInput(dpy, win, StructureNotifyMask|KeyReleaseMask|
                 ButtonReleaseMask|ButtonPressMask|
                 ExposureMask|LeaveWindowMask|PointerMotionMask);

    sizeh = XAllocSizeHints();
    sizeh->flags = PMaxSize | PMinSize;
    sizeh->min_width = sizeh->max_width = ww;
    sizeh->min_height = sizeh->max_height = wh;
    XStringListToTextProperty(&name, 1, &str);
    ch = XAllocClassHint();
    ch->res_class = name;
    ch->res_name = name;

    XSetWMProperties(dpy, win, &str, &str, NULL, 0, sizeh, NULL,
                     ch);

    XFree(ch);
    XFree(str.value);
    XFree(sizeh);

    XMapRaised(dpy, win);
    updateentries();
    drawmenu();
}
Exemplo n.º 12
0
void
drawmenu(void) {
    int curpos;
    Item *item;

    dc->x = 0;
    dc->y = 0;
    dc->w = 0;
    dc->h = height;

    dc->text_offset_y = 0;

    if(mh < height) {
        dc->text_offset_y = (height - mh) / 2;
    }

    drawrect(dc, 0, 0, mw, height, True, BG(dc, normcol));

    if(message) {
        if(messageposition == RIGHT || messageposition == CENTRE) { // Find starting position aligned text
            dc->x = mw;
            for(item = curr; item != next; item = item->right) {
                dc->x -= textw(dc, item->text);
            }
        }
        if(messageposition == CENTRE) {
            dc->x /= 2;
        }
        for(item = curr; item != next; item = item->right) {
            dc->w = textw(dc, item->text);
            drawtext(dc, item->text, normcol);
            dc->x += dc->w;
        }
    }
    else {
        if(prompt) {
            dc->w = promptw;
            drawtext(dc, prompt, selcol);
            dc->x = dc->w;
        }
        dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
        drawtext(dc, text, normcol);
        if((curpos = textnw(dc, text, cursor) + mh/2 - 2) < dc->w)
            drawrect(dc, curpos, 2 + dc->text_offset_y, 1, mh - 4, True, FG(dc, normcol));

        if(lines > 0) {
            dc->w = mw - dc->x;
            for(item = curr; item != next; item = item->right) {
                dc->y += dc->h;
                drawtext(dc, item->text, (item == sel) ? selcol : normcol);
            }
        }
        else if(matches) {
            dc->x += dc->w;
            if(curr->left) {
                dc->w = textw(dc, "<");
                drawtext(dc, "<", normcol);
                dc->x += dc->w;
            }
            for(item = curr; item != next; item = item->right) {
                dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">"));
                drawtext(dc, item->text, (item == sel) ? selcol : normcol);
                dc->x += dc->w;
            }
            dc->w = textw(dc, ">");
            dc->x = mw - dc->w;
            if(next) {
                drawtext(dc, ">", normcol);
            }
        }
    }
    mapdc(dc, win, mw, height);
}