Render text into pixmaps for borders and buttons, avoiding expose events.

SVN revision: 13121
This commit is contained in:
Kim Woelders 2005-01-29 07:41:49 +00:00
parent 4d40fa97d8
commit 359237ee15
5 changed files with 189 additions and 131 deletions

12
src/E.h
View File

@ -368,6 +368,7 @@ typedef struct
char type;
Pixmap pmap;
Pixmap mask;
int w, h;
}
PmapMask;
@ -1891,6 +1892,10 @@ void ImageclassApplyCopy(ImageClass * ic, Window win, int w,
int state, PmapMask * pmm,
int make_mask, int image_type);
void FreePmapMask(PmapMask * pmm);
void ITApply(Window win, ImageClass * ic, ImageState * is, int w,
int h, int state, int active, int sticky,
char expose, int image_type, TextClass * tc,
TextState * ts, const char *text);
/* ipc.c */
void __PRINTF__ IpcPrintf(const char *fmt, ...);
@ -2133,8 +2138,11 @@ void TextclassApply(ImageClass * ic, Window win, int w,
const char *text);
/* text.c */
TextState *TextGetState(TextClass * tclass, int active, int sticky,
int state);
TextState *TextclassGetTextState(TextClass * tclass, int state,
int active, int sticky);
void TextstateDrawText(TextState * ts, Window win,
const char *text, int x, int y, int w,
int h, int fsize, int justification);
void TextSize(TextClass * tclass, int active, int sticky,
int state, const char *text, int *width,
int *height, int fsize);

View File

@ -33,9 +33,9 @@ AwaitIclass;
#define EWIN_BORDER_PART_EVENT_MASK \
(KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
EnterWindowMask | LeaveWindowMask | PointerMotionMask | ExposureMask)
EnterWindowMask | LeaveWindowMask | PointerMotionMask)
#define EWIN_BORDER_TITLE_EVENT_MASK \
(EWIN_BORDER_PART_EVENT_MASK | ExposureMask)
(EWIN_BORDER_PART_EVENT_MASK)
static void BorderWinpartHandleEvents(XEvent * ev, void *prm);
static void BorderFrameHandleEvents(XEvent * ev, void *prm);
@ -82,42 +82,49 @@ BorderWinpartITclassApply(EWin * ewin, int i, int force)
EWinBit *ewb = &ewin->bits[i];
ImageState *is;
TextState *ts;
const char *title;
const char *txt;
if (ewb->win == None)
return;
is = ImageclassGetImageState(ewin->border->part[i].iclass,
ewin->bits[i].state,
is = ImageclassGetImageState(ewin->border->part[i].iclass, ewb->state,
ewin->active, EoIsSticky(ewin));
ts = NULL;
if (ewin->border->part[i].tclass)
ts = TextGetState(ewin->border->part[i].tclass, ewin->active,
EoIsSticky(ewin), ewin->bits[i].state);
if (!force && ewin->bits[i].is == is && ewin->bits[i].ts == ts)
return;
ewin->bits[i].is = is;
ewin->bits[i].ts = ts;
ImageclassApply(ewin->border->part[i].iclass, ewb->win,
ewb->w, ewb->h, ewin->active,
EoIsSticky(ewin), ewb->state, ewb->expose, ST_BORDER);
txt = NULL;
switch (ewin->border->part[i].flags)
{
case FLAG_TITLE:
title = EwinGetName(ewin);
if (title)
TextclassApply(ewin->border->part[i].iclass, ewb->win,
ewb->w, ewb->h, ewin->active,
EoIsSticky(ewin), ewb->state, ewb->expose,
ewin->border->part[i].tclass, title);
txt = EwinGetName(ewin);
if (txt && ewin->border->part[i].tclass)
ts = TextclassGetTextState(ewin->border->part[i].tclass, ewb->state,
ewin->active, EoIsSticky(ewin));
break;
case FLAG_MINIICON:
break;
default:
break;
}
if (!force && ewb->is == is && ewb->ts == ts)
return;
ewb->is = is;
ewb->ts = ts;
#if 0 /* FIXME - Remove? */
ImageclassApply(ewin->border->part[i].iclass, ewb->win,
ewb->w, ewb->h, ewin->active,
EoIsSticky(ewin), ewb->state, ewb->expose, ST_BORDER);
if (ts)
TextclassApply(ewin->border->part[i].iclass, ewb->win,
ewb->w, ewb->h, ewin->active,
EoIsSticky(ewin), ewb->state, ewb->expose,
ewin->border->part[i].tclass, txt);
#else
ITApply(ewb->win, ewin->border->part[i].iclass, is, ewb->w, ewb->h,
ewb->state, ewin->active, EoIsSticky(ewin), ewb->expose, ST_BORDER,
ewin->border->part[i].tclass, ts, txt);
#endif
}
static int
@ -930,6 +937,7 @@ EwinBorderEventsConfigure(EWin * ewin, int mode)
*/
#define DEBUG_BORDER_EVENTS 0
#if 0 /* FIXME - Remove? */
static void
BorderWinpartEventExpose(EWinBit * wbit, XEvent * ev __UNUSED__)
{
@ -941,6 +949,7 @@ BorderWinpartEventExpose(EWinBit * wbit, XEvent * ev __UNUSED__)
if (BorderWinpartDraw(ewin, part) && IsPropagateEwinOnQueue(ewin))
EwinPropagateShapes(ewin);
}
#endif
static void
BorderWinpartEventMouseDown(EWinBit * wbit, XEvent * ev)
@ -1092,9 +1101,11 @@ BorderWinpartHandleEvents(XEvent * ev, void *prm)
case LeaveNotify:
BorderWinpartEventLeave(wbit, ev);
break;
#if 0 /* FIXME - Remove? */
case Expose:
BorderWinpartEventExpose(wbit, ev);
break;
#endif
}
}

View File

@ -21,12 +21,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#include "ecompmgr.h" /* FIXME - Remove */
#define BUTTON_EVENT_MASK \
(ExposureMask | KeyPressMask | KeyReleaseMask | \
(KeyPressMask | KeyReleaseMask | \
ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask)
/* PointerMotionMask */
typedef struct _bgeometry
{
@ -328,12 +326,17 @@ ButtonToggle(Button * b)
void
ButtonDraw(Button * b)
{
#if 0 /* FIXME - Remove? */
ImageclassApply(b->iclass, EoGetWin(b), EoGetW(b), EoGetH(b), 0, 0, b->state,
0, ST_BUTTON);
if (b->label)
TextclassApply(b->iclass, EoGetWin(b), EoGetW(b), EoGetH(b), 0, 0,
b->state, 0, b->tclass, b->label);
#else
ITApply(EoGetWin(b), b->iclass, NULL, EoGetW(b), EoGetH(b),
b->state, 0, 0, 0, ST_BUTTON, b->tclass, NULL, b->label);
#endif
}
void
@ -630,12 +633,18 @@ FindButton(Window win)
* Button event handlers
*/
#if 0 /* FIXME - Remove? */
static void
ButtonEventExpose(Button * b, XEvent * ev __UNUSED__)
{
#if 1
if (!ECompMgrActive()) /* FIXME - Remove */
ButtonDraw(b);
#else
b = NULL;
#endif
}
#endif
static void
ButtonEventMouseDown(Button * b, XEvent * ev)
@ -784,9 +793,11 @@ ButtonHandleEvents(XEvent * ev, void *prm)
case LeaveNotify:
ButtonEventMouseOut(b, ev);
break;
#if 0 /* FIXME - Remove? */
case Expose:
ButtonEventExpose(b, ev);
break;
#endif
}
}

View File

@ -662,9 +662,8 @@ static void
ImagestateMakePmapMask(ImageState * is, Drawable win, PmapMask * pmm,
int make_mask, int w, int h, int image_type)
{
int apply, trans;
int trans;
int ww, hh;
PmapMask pmml;
#ifdef ENABLE_TRANSPARENCY
Imlib_Image *ii = NULL;
@ -716,18 +715,9 @@ ImagestateMakePmapMask(ImageState * is, Drawable win, PmapMask * pmm,
flags |= ICLASS_ATTR_USE_CM;
#endif
apply = !pmm;
if (!pmm)
pmm = &pmml;
imlib_context_set_drawable(win);
imlib_context_set_image(is->im);
#if 1 /* Remove ??? */
if (is->border)
imlib_image_set_border(is->border);
#endif
ww = imlib_image_get_width();
hh = imlib_image_get_height();
@ -837,6 +827,8 @@ ImagestateMakePmapMask(ImageState * is, Drawable win, PmapMask * pmm,
imlib_render_pixmaps_for_whole_image_at_size(&pmm->pmap, &pmm->mask,
w, h);
#endif /* ENABLE_TRANSPARENCY */
pmm->w = w;
pmm->h = h;
}
else
{
@ -868,74 +860,8 @@ ImagestateMakePmapMask(ImageState * is, Drawable win, PmapMask * pmm,
}
imlib_render_pixmaps_for_whole_image_at_size(&pmm->pmap, &pmm->mask,
pw, ph);
}
if (apply)
{
/* Rendering on drawable */
if (is->pixmapfillstyle == FILL_STRETCH || trans)
{
if (pmm->pmap)
{
ESetWindowBackgroundPixmap(disp, win, pmm->pmap);
EShapeCombineMask(disp, win, ShapeBounding, 0, 0,
pmm->mask, ShapeSet);
}
}
else
{
if (pmm->pmap)
{
ESetWindowBackgroundPixmap(disp, win, pmm->pmap);
if (pmm->mask)
EShapeCombineMaskTiled(disp, win, ShapeBounding, 0, 0,
pmm->mask, ShapeSet, w, h);
}
}
FreePmapMask(pmm);
XClearWindow(disp, win);
}
else
{
/* Making pmap/mask */
if (is->pixmapfillstyle == FILL_STRETCH || trans)
{
/* pmap and mask are already rendered at the correct size */
}
else
{
/* Create new full sized pixmaps and fill them with the */
/* pmap and mask tiles */
Pixmap tp = 0, tm = 0;
GC gc;
XGCValues gcv;
tp = ecore_x_pixmap_new(win, w, h, VRoot.depth);
gcv.fill_style = FillTiled;
gcv.tile = pmm->pmap;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
gc = XCreateGC(disp, tp, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
XFillRectangle(disp, tp, gc, 0, 0, w, h);
XFreeGC(disp, gc);
if (pmm->mask)
{
tm = ecore_x_pixmap_new(win, w, h, 1);
gcv.fill_style = FillTiled;
gcv.tile = pmm->mask;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
gc = XCreateGC(disp, tm, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
XFillRectangle(disp, tm, gc, 0, 0, w, h);
XFreeGC(disp, gc);
}
FreePmapMask(pmm);
pmm->type = 0;
pmm->pmap = tp;
pmm->mask = tm;
}
pmm->w = pw;
pmm->h = ph;
}
#ifdef ENABLE_TRANSPARENCY
@ -1046,17 +972,17 @@ ImagestateDrawBevel(ImageState * is, Drawable win, GC gc, int w, int h)
}
void
ImageclassApply(ImageClass * ic, Window win, int w, int h, int active,
int sticky, int state, char expose, int image_type)
ITApply(Window win, ImageClass * ic, ImageState * is, int w, int h, int state,
int active, int sticky, char expose, int image_type, TextClass * tc,
TextState * ts, const char *text)
{
ImageState *is;
if ((!ic) || (!win))
if (win == None || !ic)
return;
if (w < 0)
/* FIXME - Why? */
if (w <= 0 || h <= 0)
GetWinWH(win, (unsigned int *)&w, (unsigned int *)&h);
if ((w < 0) || (h < 0))
if (w <= 0 || h <= 0)
return;
#if 0 /* Try not using the draw queue here. */
@ -1093,28 +1019,76 @@ ImageclassApply(ImageClass * ic, Window win, int w, int h, int active,
if (ic->external)
return;
is = ImageclassGetImageState(ic, state, active, sticky);
if (!is)
is = ImageclassGetImageState(ic, state, active, sticky);
if (!is)
return;
if (!expose)
if (tc && text)
{
if (!ts)
ts = TextclassGetTextState(tc, state, active, sticky);
}
if (!expose) // FIXME - Hmmm
{
if (is->im == NULL && is->im_file)
ImagestateRealize(is);
if (is->im)
{
ImagestateMakePmapMask(is, win, NULL, 1, w, h, image_type);
PmapMask pmm;
int decache = 1;
ImagestateMakePmapMask(is, win, &pmm, 1, w, h, image_type);
if (pmm.pmap)
{
if (ts && text)
{
TextstateDrawText(ts, pmm.pmap, text, ic->padding.left,
ic->padding.top,
w - (ic->padding.left +
ic->padding.right),
h - (ic->padding.top +
ic->padding.bottom),
0, tc->justification);
decache = 1;
}
/* Set window pixmap */
if (pmm.w == w && pmm.h == h)
{
ESetWindowBackgroundPixmap(disp, win, pmm.pmap);
EShapeCombineMask(disp, win, ShapeBounding, 0, 0,
pmm.mask, ShapeSet);
}
else
{
/* Tiled */
ESetWindowBackgroundPixmap(disp, win, pmm.pmap);
if (pmm.mask)
EShapeCombineMaskTiled(disp, win, ShapeBounding, 0, 0,
pmm.mask, ShapeSet, w, h);
}
}
FreePmapMask(&pmm);
XClearWindow(disp, win);
if ((is->unloadable) || (Conf.memory_paranoia))
{
imlib_context_set_image(is->im);
imlib_free_image();
if (decache)
imlib_free_image_and_decache();
else
imlib_free_image();
is->im = NULL;
}
}
else
{
/* FIXME - No text */
ESetWindowBackground(disp, win, is->bg.pixel);
XClearWindow(disp, win);
}
@ -1130,6 +1104,14 @@ ImageclassApply(ImageClass * ic, Window win, int w, int h, int active,
}
}
void
ImageclassApply(ImageClass * ic, Window win, int w, int h, int active,
int sticky, int state, char expose, int image_type)
{
ITApply(win, ic, NULL, w, h, state, active, sticky, expose, image_type,
NULL, NULL, NULL);
}
void
ImageclassApplyCopy(ImageClass * ic, Window win, int w, int h, int active,
int sticky, int state, PmapMask * pmm, int make_mask,
@ -1161,6 +1143,44 @@ ImageclassApplyCopy(ImageClass * ic, Window win, int w, int h, int active,
{
ImagestateMakePmapMask(is, win, pmm, make_mask, w, h, image_type);
if (pmm->pmap)
{
if (pmm->w != w || pmm->h != h)
{
/* Create new full sized pixmaps and fill them with the */
/* pmap and mask tiles */
Pixmap tp = 0, tm = 0;
XGCValues gcv;
tp = ecore_x_pixmap_new(win, w, h, VRoot.depth);
gcv.fill_style = FillTiled;
gcv.tile = pmm->pmap;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
gc = XCreateGC(disp, tp, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
XFillRectangle(disp, tp, gc, 0, 0, w, h);
XFreeGC(disp, gc);
if (pmm->mask)
{
tm = ecore_x_pixmap_new(win, w, h, 1);
gcv.fill_style = FillTiled;
gcv.tile = pmm->mask;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
gc = XCreateGC(disp, tm, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin,
&gcv);
XFillRectangle(disp, tm, gc, 0, 0, w, h);
XFreeGC(disp, gc);
}
FreePmapMask(pmm);
pmm->type = 0;
pmm->pmap = tp;
pmm->mask = tm;
}
}
if ((is->unloadable) || (Conf.memory_paranoia))
{
imlib_context_set_image(is->im);

View File

@ -32,7 +32,7 @@ static void TextDrawRotBack(Window win, Drawable drawable, int x, int y,
int w, int h, TextState * ts);
TextState *
TextGetState(TextClass * tclass, int active, int sticky, int state)
TextclassGetTextState(TextClass * tclass, int state, int active, int sticky)
{
if (active)
{
@ -235,7 +235,7 @@ TextSize(TextClass * tclass, int active, int sticky, int state,
if (!text)
return;
ts = TextGetState(tclass, active, sticky, state);
ts = TextclassGetTextState(tclass, state, active, sticky);
if (!ts)
return;
@ -304,26 +304,17 @@ TextSize(TextClass * tclass, int active, int sticky, int state,
}
void
TextDraw(TextClass * tclass, Window win, int active, int sticky, int state,
const char *text, int x, int y, int w, int h, int fsize __UNUSED__,
int justification)
TextstateDrawText(TextState * ts, Window win, const char *text, int x, int y,
int w, int h, int fsize __UNUSED__, int justification)
{
const char *str;
char **lines;
int i, num_lines;
TextState *ts;
int xx, yy;
static GC gc = 0;
int textwidth_limit, offset_x, offset_y;
Pixmap drawable;
if (!tclass || !text)
return;
ts = TextGetState(tclass, active, sticky, state);
if (!ts)
return;
TextStateLoadFont(ts);
/* Do encoding conversion, if necessary */
@ -774,6 +765,23 @@ TextDraw(TextClass * tclass, Window win, int active, int sticky, int state,
freestrlist(lines, num_lines);
}
void
TextDraw(TextClass * tclass, Window win, int active, int sticky, int state,
const char *text, int x, int y, int w, int h, int fsize,
int justification)
{
TextState *ts;
if (!tclass || !text)
return;
ts = TextclassGetTextState(tclass, state, active, sticky);
if (!ts)
return;
TextstateDrawText(ts, win, text, x, y, w, h, fsize, justification);
}
void
TextDrawRotTo(Window win, Drawable * drawable, int x, int y, int w, int h,
TextState * ts)