From 0963afc29c62e6350fffd188a382050889f04378 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 24 Nov 2003 17:11:00 +0000 Subject: Add support for CM_TRANSLUCENT property. reviewed by: Keith Packard --- ChangeLog | 8 ++++ xcompmgr.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0abb9f..cbd0d81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2003-11-24 Matthew Hawn + + reviewed by: Keith Packard + + * xcompmgr.c: (map_win), (unmap_win), (get_trans_prop), + (determine_mode), (add_win), (main): + Add support for CM_TRANSLUCENT property. + 2003-11-23 Keith Packard * xcompmgr.c: (make_shadow), (root_tile), (win_extents), diff --git a/xcompmgr.c b/xcompmgr.c index f17c5cb..b56cdcf 100644 --- a/xcompmgr.c +++ b/xcompmgr.c @@ -22,6 +22,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ + +/* Modified by Matthew Hawn. I don't know what to say here so follow what it + says above. Not that I can really do anything about it +*/ + + #include #include #include @@ -74,6 +80,15 @@ Picture blackPicture; Picture rootTile; XserverRegion allDamage; int root_height, root_width; + + +/* find these once and be done with it */ +Atom transPropAtom; +Atom intAtom; + +/* translucency property name */ +#define TRANS_PROP "CM_TRANSLUCENCY" + conv *gaussianMap; #define WINDOW_SOLID 0 @@ -598,6 +613,10 @@ map_win (Display *dpy, Window id, unsigned long sequence) if (!w) return; w->a.map_state = IsViewable; + + /* make sure we know if property was changed */ + XSelectInput(dpy, id, PropertyChangeMask); + w->damaged = 0; } @@ -615,6 +634,96 @@ unmap_win (Display *dpy, Window id) add_damage (dpy, w->extents); /* destroys region */ w->extents = None; } + + /* don't care about properties anymore */ + XSelectInput(dpy, id, 0); +} + + + +/* Get the translucency prop from window + not found: -1 + otherwise the value + + */ +static int +get_trans_prop(Display *dpy, win *w) +{ + Atom actual; + int format; + unsigned long n, left; + + char *data; + XGetWindowProperty(dpy, w->id, transPropAtom, 0L, 1L, False, intAtom, &actual, &format, + &n, &left, (unsigned char **) &data); + if (data != None) + { + int i = (int) *data; + XFree( (void *) data); + return i; + } + return -1; + +} + +/* determine mode for window all in one place. + Future might check for menu flag and other cool things +*/ + + +static int +determine_mode(Display *dpy, win *w) +{ + int mode; + + /* if trans prop == -1 fall back on previous tests*/ + + int p = get_trans_prop(dpy, w); + if ( p != -1 ) + { + if (p > 0) + { + /* don't really care about the value as long as > 0 */ + mode = WINDOW_TRANS; + } + else + { + mode = WINDOW_SOLID; + } + } + + + + else + { + XRenderPictFormat *format; + if (w->a.class == InputOnly) + { + format = 0; + } + else + { + format = XRenderFindVisualFormat (dpy, w->a.visual); + } + + + + if (format && format->type == PictTypeDirect && format->direct.alphaMask) + { + mode = WINDOW_ARGB; + } + else if (w->a.override_redirect) + { + /* changed this as a lot of window managers set this for all top + level windows */ + mode = WINDOW_SOLID; + } + else + { + mode = WINDOW_SOLID; + } + } + return mode; } static void @@ -669,12 +778,11 @@ add_win (Display *dpy, Window id, Window prev) new->shadow_height = 0; new->borderSize = None; new->extents = None; - if (format && format->type == PictTypeDirect && format->direct.alphaMask) - new->mode = WINDOW_ARGB; - else if (new->a.override_redirect) - new->mode = WINDOW_TRANS; - else - new->mode = WINDOW_SOLID; + + + /* moved mode setting to one place */ + new->mode = determine_mode(dpy, new); + new->next = *p; *p = new; if (new->a.map_state == IsViewable) @@ -940,6 +1048,11 @@ main (int argc, char **argv) XSetErrorHandler (error); scr = DefaultScreen (dpy); root = RootWindow (dpy, scr); + + /* get atoms */ + transPropAtom = XInternAtom(dpy, TRANS_PROP, False); + intAtom = XInternAtom(dpy, "INTEGER", True); + pa.subwindow_mode = IncludeInferiors; gaussianMap = make_gaussian_map(dpy, SHADOW_RADIUS); @@ -953,10 +1066,10 @@ main (int argc, char **argv) c.red = c.green = c.blue = 0; c.alpha = 0xc0c0; XRenderFillRectangle (dpy, PictOpSrc, transPicture, &c, 0, 0, 1, 1); - + root_width = DisplayWidth (dpy, scr); root_height = DisplayHeight (dpy, scr); - + rootPicture = XRenderCreatePicture (dpy, root, XRenderFindVisualFormat (dpy, DefaultVisual (dpy, scr)), @@ -1008,7 +1121,7 @@ main (int argc, char **argv) #if INTERVAL int busy_start = 0; #endif -/* dump_wins (); */ + /* dump_wins (); */ do { XNextEvent (dpy, &ev); #if INTERVAL @@ -1089,6 +1202,23 @@ main (int argc, char **argv) } } } + /* check if Trans property was changed */ + if (ev.xproperty.atom == transPropAtom) + { + /* reset mode and redraw window */ + win * w = find_win(dpy, ev.xproperty.window); + if (w) + { + w->mode = determine_mode(dpy, w); + if (w->extents) + { + XserverRegion damage; + damage = XFixesCreateRegion (dpy, 0, 0); + XFixesCopyRegion (dpy, damage, w->extents); + add_damage (dpy, damage); + } + } + } break; default: if (ev.type == damage_event + XDamageNotify) -- cgit v1.2.3-70-g09d2